Use an internal version of [Static]SamplerBindingLayout.

Bug: TBD
Change-Id: I69562468df7fec140cfb929d212be624804de534
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/182923
Reviewed-by: Loko Kung <lokokung@google.com>
Reviewed-by: Austin Eng <enga@chromium.org>
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
diff --git a/generator/dawn_json_generator.py b/generator/dawn_json_generator.py
index ba310db..11e8809 100644
--- a/generator/dawn_json_generator.py
+++ b/generator/dawn_json_generator.py
@@ -937,15 +937,6 @@
         return as_cppType(typ.name)
 
 
-def as_formatType(typ):
-    # Unsigned integral types
-    if typ.json_data['type'] in ['bool', 'uint32_t', 'uint64_t']:
-        return 'u'
-
-    # Defaults everything else to strings.
-    return 's'
-
-
 def c_methods(params, typ):
     return typ.methods + [
         # TODO(dawn:2234): Deprecated. Remove when no longer used.
@@ -1024,7 +1015,6 @@
             'convert_cType_to_cppType': convert_cType_to_cppType,
             'as_varName': as_varName,
             'decorate': decorate,
-            'as_formatType': as_formatType,
             'as_ktName': as_ktName,
         }
 
diff --git a/generator/templates/dawn/native/api_absl_format.cpp b/generator/templates/dawn/native/api_absl_format.cpp
index 2880e7a..6e8168a 100644
--- a/generator/templates/dawn/native/api_absl_format.cpp
+++ b/generator/templates/dawn/native/api_absl_format.cpp
@@ -69,39 +69,6 @@
         {% endfor %}
     {% endfor %}
 
-    //
-    // Compatible with absl::StrFormat (Needs to be disjoint from having a 'label' for now.)
-    // Currently uses a hard-coded list to determine which structures are actually supported. If
-    // additional structures are added, be sure to update the header file's list as well.
-    //
-    using absl::ParsedFormat;
-
-    {% for type in by_category["structure"] %}
-        {% if type.name.get() in [
-             "sampler binding layout",
-           ]
-        %}
-        absl::FormatConvertResult<absl::FormatConversionCharSet::kString>
-            AbslFormatConvert(const {{as_cppType(type.name)}}& value,
-                              const absl::FormatConversionSpec& spec,
-                              absl::FormatSink* s) {
-            {% set members = [] %}
-            {% set format = [] %}
-            {% set template = [] %}
-            {% for member in type.members %}
-                {% set memberName = member.name.camelCase() %}
-                {% do members.append("value." + memberName) %}
-                {% do format.append(memberName + ": %" + as_formatType(member)) %}
-                {% do template.append("'" + as_formatType(member) + "'") %}
-            {% endfor %}
-            static const auto* const fmt =
-                new ParsedFormat<{{template|join(",")}}>("{ {{format|join(", ")}} }");
-            s->Append(absl::StrFormat(*fmt, {{members|join(", ")}}));
-            return {true};
-        }
-        {% endif %}
-    {% endfor %}
-
 }  // namespace {{native_namespace}}
 
 {% set namespace = metadata.namespace %}
diff --git a/generator/templates/dawn/native/api_absl_format.h b/generator/templates/dawn/native/api_absl_format.h
index 5b98c7c..96d5128 100644
--- a/generator/templates/dawn/native/api_absl_format.h
+++ b/generator/templates/dawn/native/api_absl_format.h
@@ -61,23 +61,6 @@
         {% endfor %}
     {% endfor %}
 
-    //
-    // Compatible with absl::StrFormat (Needs to be disjoint from having a 'label' for now.)
-    // Currently uses a hard-coded list to determine which structures are actually supported. If
-    // additional structures are added, be sure to update the cpp file's list as well.
-    //
-    {% for type in by_category["structure"] %}
-        {% if type.name.get() in [
-             "sampler binding layout",
-           ]
-        %}
-        absl::FormatConvertResult<absl::FormatConversionCharSet::kString>
-            AbslFormatConvert(const {{as_cppType(type.name)}}& value,
-                              const absl::FormatConversionSpec& spec,
-                              absl::FormatSink* s);
-        {% endif %}
-    {% endfor %}
-
 } // namespace {{native_namespace}}
 
 {% set namespace = metadata.namespace %}
diff --git a/src/dawn/native/BindGroup.cpp b/src/dawn/native/BindGroup.cpp
index 6f5caae..61d8974 100644
--- a/src/dawn/native/BindGroup.cpp
+++ b/src/dawn/native/BindGroup.cpp
@@ -225,7 +225,7 @@
 
 MaybeError ValidateSamplerBinding(const DeviceBase* device,
                                   const BindGroupEntry& entry,
-                                  const SamplerBindingLayout& layout) {
+                                  const SamplerBindingInfo& layout) {
     DAWN_INVALID_IF(entry.sampler == nullptr, "Binding entry sampler not set.");
 
     DAWN_INVALID_IF(entry.sampler->IsYCbCr(),
@@ -392,14 +392,14 @@
                                  i, layout);
                 return {};
             },
-            [&](const SamplerBindingLayout& layout) -> MaybeError {
+            [&](const SamplerBindingInfo& layout) -> MaybeError {
                 DAWN_TRY_CONTEXT(ValidateSamplerBinding(device, entry, layout),
                                  "validating entries[%u] as a Sampler."
                                  "\nExpected entry layout: %s",
                                  i, layout);
                 return {};
             },
-            [&](const StaticSamplerHolderBindingLayout& layout) -> MaybeError {
+            [&](const StaticSamplerBindingInfo& layout) -> MaybeError {
                 return DAWN_VALIDATION_ERROR(
                     "entries[%u] is provided when the layout contains a static sampler for that "
                     "binding.",
@@ -583,7 +583,7 @@
     DAWN_ASSERT(!IsError());
     const BindGroupLayoutInternalBase* layout = GetLayout();
     DAWN_ASSERT(bindingIndex < layout->GetBindingCount());
-    DAWN_ASSERT(std::holds_alternative<SamplerBindingLayout>(
+    DAWN_ASSERT(std::holds_alternative<SamplerBindingInfo>(
         layout->GetBindingInfo(bindingIndex).bindingLayout));
     return static_cast<SamplerBase*>(mBindingData.bindings[bindingIndex].Get());
 }
diff --git a/src/dawn/native/BindGroupLayoutInternal.cpp b/src/dawn/native/BindGroupLayoutInternal.cpp
index 4c3cc41..0fa3bf1 100644
--- a/src/dawn/native/BindGroupLayoutInternal.cpp
+++ b/src/dawn/native/BindGroupLayoutInternal.cpp
@@ -352,13 +352,13 @@
                    layoutA.hasDynamicOffset != layoutB.hasDynamicOffset ||
                    layoutA.minBindingSize != layoutB.minBindingSize;
         },
-        [&](const SamplerBindingLayout& layoutA) -> bool {
-            const SamplerBindingLayout& layoutB = std::get<SamplerBindingLayout>(b.bindingLayout);
+        [&](const SamplerBindingInfo& layoutA) -> bool {
+            const SamplerBindingInfo& layoutB = std::get<SamplerBindingInfo>(b.bindingLayout);
             return layoutA.type != layoutB.type;
         },
-        [&](const StaticSamplerHolderBindingLayout& layoutA) -> bool {
-            const StaticSamplerHolderBindingLayout& layoutB =
-                std::get<StaticSamplerHolderBindingLayout>(b.bindingLayout);
+        [&](const StaticSamplerBindingInfo& layoutA) -> bool {
+            const StaticSamplerBindingInfo& layoutB =
+                std::get<StaticSamplerBindingInfo>(b.bindingLayout);
             return layoutA.sampler != layoutB.sampler;
         },
         [&](const TextureBindingInfo& layoutA) -> bool {
@@ -395,7 +395,7 @@
     if (binding->buffer.type != wgpu::BufferBindingType::Undefined) {
         bindingInfo.bindingLayout = BufferBindingInfo(binding->buffer);
     } else if (binding->sampler.type != wgpu::SamplerBindingType::Undefined) {
-        bindingInfo.bindingLayout = binding->sampler;
+        bindingInfo.bindingLayout = SamplerBindingInfo(binding->sampler);
     } else if (binding->texture.sampleType != wgpu::TextureSampleType::Undefined) {
         bindingInfo.bindingLayout =
             TextureBindingInfo(binding->texture.WithTrivialFrontendDefaults());
@@ -403,9 +403,7 @@
         bindingInfo.bindingLayout =
             StorageTextureBindingInfo(binding->storageTexture.WithTrivialFrontendDefaults());
     } else if (auto* staticSamplerBindingLayout = binding.Get<StaticSamplerBindingLayout>()) {
-        StaticSamplerHolderBindingLayout bindingLayout;
-        bindingLayout.sampler = staticSamplerBindingLayout->sampler;
-        bindingInfo.bindingLayout = bindingLayout;
+        bindingInfo.bindingLayout = StaticSamplerBindingInfo(*staticSamplerBindingLayout);
     } else {
         DAWN_UNREACHABLE();
     }
@@ -469,8 +467,8 @@
             break;
         }
         case BindingInfoType::Sampler: {
-            const auto& aLayout = std::get<SamplerBindingLayout>(aInfo.bindingLayout);
-            const auto& bLayout = std::get<SamplerBindingLayout>(bInfo.bindingLayout);
+            const auto& aLayout = std::get<SamplerBindingInfo>(aInfo.bindingLayout);
+            const auto& bLayout = std::get<SamplerBindingInfo>(bInfo.bindingLayout);
             if (aLayout.type != bLayout.type) {
                 return aLayout.type < bLayout.type;
             }
@@ -505,8 +503,8 @@
             break;
         }
         case BindingInfoType::StaticSampler: {
-            const auto& aLayout = std::get<StaticSamplerHolderBindingLayout>(aInfo.bindingLayout);
-            const auto& bLayout = std::get<StaticSamplerHolderBindingLayout>(bInfo.bindingLayout);
+            const auto& aLayout = std::get<StaticSamplerBindingInfo>(aInfo.bindingLayout);
+            const auto& bLayout = std::get<StaticSamplerBindingInfo>(bInfo.bindingLayout);
             if (aLayout.sampler != bLayout.sampler) {
                 return aLayout.sampler < bLayout.sampler;
             }
@@ -630,7 +628,7 @@
                 recorder.Record(BindingInfoType::Buffer, layout.hasDynamicOffset, layout.type,
                                 layout.minBindingSize);
             },
-            [&](const SamplerBindingLayout& layout) {
+            [&](const SamplerBindingInfo& layout) {
                 recorder.Record(BindingInfoType::Sampler, layout.type);
             },
             [&](const TextureBindingInfo& layout) {
@@ -641,7 +639,7 @@
                 recorder.Record(BindingInfoType::StorageTexture, layout.access, layout.format,
                                 layout.viewDimension);
             },
-            [&](const StaticSamplerHolderBindingLayout& layout) {
+            [&](const StaticSamplerBindingInfo& layout) {
                 recorder.Record(BindingInfoType::StaticSampler, layout.sampler->GetContentHash());
             });
     }
diff --git a/src/dawn/native/BindingInfo.cpp b/src/dawn/native/BindingInfo.cpp
index c7325e6..84bf0a0 100644
--- a/src/dawn/native/BindingInfo.cpp
+++ b/src/dawn/native/BindingInfo.cpp
@@ -30,6 +30,7 @@
 #include "dawn/common/MatchVariant.h"
 #include "dawn/native/ChainUtils.h"
 #include "dawn/native/Limits.h"
+#include "dawn/native/Sampler.h"
 
 namespace dawn::native {
 
@@ -37,12 +38,12 @@
     return MatchVariant(
         info.bindingLayout,
         [](const BufferBindingInfo&) -> BindingInfoType { return BindingInfoType::Buffer; },
-        [](const SamplerBindingLayout&) -> BindingInfoType { return BindingInfoType::Sampler; },
+        [](const SamplerBindingInfo&) -> BindingInfoType { return BindingInfoType::Sampler; },
         [](const TextureBindingInfo&) -> BindingInfoType { return BindingInfoType::Texture; },
         [](const StorageTextureBindingInfo&) -> BindingInfoType {
             return BindingInfoType::StorageTexture;
         },
-        [](const StaticSamplerHolderBindingLayout&) -> BindingInfoType {
+        [](const StaticSamplerBindingInfo&) -> BindingInfoType {
             return BindingInfoType::StaticSampler;
         });
 }
@@ -234,14 +235,24 @@
       minBindingSize(apiLayout.minBindingSize),
       hasDynamicOffset(apiLayout.hasDynamicOffset) {}
 
-StorageTextureBindingInfo::StorageTextureBindingInfo() = default;
-StorageTextureBindingInfo::StorageTextureBindingInfo(const StorageTextureBindingLayout& apiLayout)
-    : format(apiLayout.format), viewDimension(apiLayout.viewDimension), access(apiLayout.access) {}
-
 TextureBindingInfo::TextureBindingInfo() {}
 
 TextureBindingInfo::TextureBindingInfo(const TextureBindingLayout& apiLayout)
     : sampleType(apiLayout.sampleType),
       viewDimension(apiLayout.viewDimension),
       multisampled(apiLayout.multisampled) {}
+
+StorageTextureBindingInfo::StorageTextureBindingInfo() = default;
+
+StorageTextureBindingInfo::StorageTextureBindingInfo(const StorageTextureBindingLayout& apiLayout)
+    : format(apiLayout.format), viewDimension(apiLayout.viewDimension), access(apiLayout.access) {}
+
+SamplerBindingInfo::SamplerBindingInfo() = default;
+
+SamplerBindingInfo::SamplerBindingInfo(const SamplerBindingLayout& apiLayout)
+    : type(apiLayout.type) {}
+
+StaticSamplerBindingInfo::StaticSamplerBindingInfo(const StaticSamplerBindingLayout& apiLayout)
+    : sampler(apiLayout.sampler) {}
+
 }  // namespace dawn::native
diff --git a/src/dawn/native/BindingInfo.h b/src/dawn/native/BindingInfo.h
index 87d8a26..416351c 100644
--- a/src/dawn/native/BindingInfo.h
+++ b/src/dawn/native/BindingInfo.h
@@ -66,10 +66,6 @@
     StaticSampler
 };
 
-struct StaticSamplerHolderBindingLayout {
-    Ref<SamplerBase> sampler;
-};
-
 // A mirror of wgpu::BufferBindingLayout for use inside dawn::native.
 struct BufferBindingInfo {
     BufferBindingInfo();
@@ -104,6 +100,23 @@
     wgpu::StorageTextureAccess access;
 };
 
+// A mirror of wgpu::SamplerBindingLayout for use inside dawn::native.
+struct SamplerBindingInfo {
+    SamplerBindingInfo();
+    explicit SamplerBindingInfo(const SamplerBindingLayout& apiLayout);
+
+    // For shader reflection NonFiltering is never used and Filtering is used for any `sampler`.
+    wgpu::SamplerBindingType type;
+};
+
+// A mirror of wgpu::StaticSamplerBindingLayout for use inside dawn::native.
+struct StaticSamplerBindingInfo {
+    explicit StaticSamplerBindingInfo(const StaticSamplerBindingLayout& apiLayout);
+
+    // Holds a ref instead of an unowned pointer.
+    Ref<SamplerBase> sampler;
+};
+
 // A mirror of wgpu::ExternalTextureBindingLayout for use inside dawn::native.
 struct ExternalTextureBindingInfo {};
 
@@ -112,10 +125,10 @@
     wgpu::ShaderStage visibility;
 
     std::variant<BufferBindingInfo,
-                 SamplerBindingLayout,
+                 SamplerBindingInfo,
                  TextureBindingInfo,
                  StorageTextureBindingInfo,
-                 StaticSamplerHolderBindingLayout>
+                 StaticSamplerBindingInfo>
         bindingLayout;
 };
 
diff --git a/src/dawn/native/PassResourceUsageTracker.cpp b/src/dawn/native/PassResourceUsageTracker.cpp
index 1b65869..35f18d9 100644
--- a/src/dawn/native/PassResourceUsageTracker.cpp
+++ b/src/dawn/native/PassResourceUsageTracker.cpp
@@ -160,8 +160,8 @@
                         DAWN_UNREACHABLE();
                 }
             },
-            [&](const SamplerBindingLayout&) {},  //
-            [&](const StaticSamplerHolderBindingLayout&) {});
+            [&](const SamplerBindingInfo&) {},  //
+            [&](const StaticSamplerBindingInfo&) {});
     }
 
     for (const Ref<ExternalTextureBase>& externalTexture : group->GetBoundExternalTextures()) {
@@ -226,7 +226,7 @@
                 mUsage.referencedTextures.insert(
                     group->GetBindingAsTextureView(index)->GetTexture());
             },
-            [](const SamplerBindingLayout&) {}, [](const StaticSamplerHolderBindingLayout&) {});
+            [](const SamplerBindingInfo&) {}, [](const StaticSamplerBindingInfo&) {});
     }
 
     for (const Ref<ExternalTextureBase>& externalTexture : group->GetBoundExternalTextures()) {
diff --git a/src/dawn/native/PipelineLayout.cpp b/src/dawn/native/PipelineLayout.cpp
index dcc6b6f..db43c4a 100644
--- a/src/dawn/native/PipelineLayout.cpp
+++ b/src/dawn/native/PipelineLayout.cpp
@@ -240,13 +240,7 @@
                 entry.buffer.type = bindingInfo.type;
                 entry.buffer.minBindingSize = bindingInfo.minBindingSize;
             },
-            [&](const SamplerBindingInfo& bindingInfo) {
-                if (bindingInfo.isComparison) {
-                    entry.sampler.type = wgpu::SamplerBindingType::Comparison;
-                } else {
-                    entry.sampler.type = wgpu::SamplerBindingType::Filtering;
-                }
-            },
+            [&](const SamplerBindingInfo& bindingInfo) { entry.sampler.type = bindingInfo.type; },
             [&](const TextureBindingInfo& bindingInfo) {
                 entry.texture.sampleType = bindingInfo.sampleType;
                 entry.texture.viewDimension = bindingInfo.viewDimension;
diff --git a/src/dawn/native/ShaderModule.cpp b/src/dawn/native/ShaderModule.cpp
index b1b278f..356f320 100644
--- a/src/dawn/native/ShaderModule.cpp
+++ b/src/dawn/native/ShaderModule.cpp
@@ -572,14 +572,14 @@
             return {};
         },
         [&](const SamplerBindingInfo& bindingInfo) -> MaybeError {
-            const SamplerBindingLayout& bindingLayout =
-                std::get<SamplerBindingLayout>(layoutInfo.bindingLayout);
+            const SamplerBindingInfo& bindingLayout =
+                std::get<SamplerBindingInfo>(layoutInfo.bindingLayout);
             DAWN_INVALID_IF(
                 (bindingLayout.type == wgpu::SamplerBindingType::Comparison) !=
-                    bindingInfo.isComparison,
+                    (bindingInfo.type == wgpu::SamplerBindingType::Comparison),
                 "The sampler type in the shader (comparison: %u) doesn't match the type in "
                 "the layout (comparison: %u).",
-                bindingInfo.isComparison,
+                bindingInfo.type == wgpu::SamplerBindingType::Comparison,
                 bindingLayout.type == wgpu::SamplerBindingType::Comparison);
             return {};
         },
@@ -859,10 +859,10 @@
                 SamplerBindingInfo bindingInfo = {};
                 switch (resource.resource_type) {
                     case tint::inspector::ResourceBinding::ResourceType::kSampler:
-                        bindingInfo.isComparison = false;
+                        bindingInfo.type = wgpu::SamplerBindingType::Filtering;
                         break;
                     case tint::inspector::ResourceBinding::ResourceType::kComparisonSampler:
-                        bindingInfo.isComparison = true;
+                        bindingInfo.type = wgpu::SamplerBindingType::Comparison;
                         break;
                     default:
                         DAWN_UNREACHABLE();
@@ -1177,13 +1177,13 @@
         const BindingInfo& samplerInfo =
             samplerBGL->GetBindingInfo(samplerBGL->GetBindingIndex(pair.sampler.binding));
         bool samplerIsFiltering = false;
-        if (std::holds_alternative<StaticSamplerHolderBindingLayout>(samplerInfo.bindingLayout)) {
-            const StaticSamplerHolderBindingLayout& samplerLayout =
-                std::get<StaticSamplerHolderBindingLayout>(samplerInfo.bindingLayout);
+        if (std::holds_alternative<StaticSamplerBindingInfo>(samplerInfo.bindingLayout)) {
+            const StaticSamplerBindingInfo& samplerLayout =
+                std::get<StaticSamplerBindingInfo>(samplerInfo.bindingLayout);
             samplerIsFiltering = samplerLayout.sampler->IsFiltering();
         } else {
-            const SamplerBindingLayout& samplerLayout =
-                std::get<SamplerBindingLayout>(samplerInfo.bindingLayout);
+            const SamplerBindingInfo& samplerLayout =
+                std::get<SamplerBindingInfo>(samplerInfo.bindingLayout);
             samplerIsFiltering = (samplerLayout.type == wgpu::SamplerBindingType::Filtering);
         }
         if (!samplerIsFiltering) {
diff --git a/src/dawn/native/ShaderModule.h b/src/dawn/native/ShaderModule.h
index de83e17..66c5560 100644
--- a/src/dawn/native/ShaderModule.h
+++ b/src/dawn/native/ShaderModule.h
@@ -155,12 +155,6 @@
                                            tint::ast::transform::DataMap* outputs,
                                            OwnedCompilationMessages* messages);
 
-// Mirrors wgpu::SamplerBindingLayout but instead stores a single boolean
-// for isComparison instead of a wgpu::SamplerBindingType enum.
-struct SamplerBindingInfo {
-    bool isComparison;
-};
-
 // 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 319c432..1c005af 100644
--- a/src/dawn/native/d3d11/BindGroupTrackerD3D11.cpp
+++ b/src/dawn/native/d3d11/BindGroupTrackerD3D11.cpp
@@ -228,8 +228,8 @@
                         return {};
                     },
                     [](const TextureBindingInfo&) -> MaybeError { return {}; },
-                    [](const SamplerBindingLayout&) -> MaybeError { return {}; },
-                    [](const StaticSamplerHolderBindingLayout&) -> MaybeError {
+                    [](const SamplerBindingInfo&) -> MaybeError { return {}; },
+                    [](const StaticSamplerBindingInfo&) -> MaybeError {
                         // Static samplers are implemented in the frontend on
                         // D3D11.
                         DAWN_UNREACHABLE();
@@ -374,13 +374,13 @@
                 }
                 return {};
             },
-            [&](const StaticSamplerHolderBindingLayout&) -> MaybeError {
+            [&](const StaticSamplerBindingInfo&) -> MaybeError {
                 // Static samplers are implemented in the frontend on
                 // D3D11.
                 DAWN_UNREACHABLE();
                 return {};
             },
-            [&](const SamplerBindingLayout&) -> MaybeError {
+            [&](const SamplerBindingInfo&) -> MaybeError {
                 Sampler* sampler = ToBackend(group->GetBindingAsSampler(bindingIndex));
                 ID3D11SamplerState* d3d11SamplerState = sampler->GetD3D11SamplerState();
                 if (bindingVisibility & wgpu::ShaderStage::Vertex) {
@@ -517,12 +517,12 @@
                         DAWN_UNREACHABLE();
                 }
             },
-            [&](const StaticSamplerHolderBindingLayout&) {
+            [&](const StaticSamplerBindingInfo&) {
                 // Static samplers are implemented in the frontend on
                 // D3D11.
                 DAWN_UNREACHABLE();
             },
-            [&](const SamplerBindingLayout&) {
+            [&](const SamplerBindingInfo&) {
                 ID3D11SamplerState* nullSampler = nullptr;
                 if (bindingVisibility & wgpu::ShaderStage::Vertex) {
                     deviceContext->VSSetSamplers(bindingSlot, 1, &nullSampler);
diff --git a/src/dawn/native/d3d11/PipelineLayoutD3D11.cpp b/src/dawn/native/d3d11/PipelineLayoutD3D11.cpp
index 5490a3c..4f6762d 100644
--- a/src/dawn/native/d3d11/PipelineLayoutD3D11.cpp
+++ b/src/dawn/native/d3d11/PipelineLayoutD3D11.cpp
@@ -81,10 +81,10 @@
                             DAWN_UNREACHABLE();
                     }
                 },
-                [&](const SamplerBindingLayout&) {
+                [&](const SamplerBindingInfo&) {
                     mIndexInfo[group][bindingIndex] = samplerIndex++;
                 },
-                [&](const StaticSamplerHolderBindingLayout&) {
+                [&](const StaticSamplerBindingInfo&) {
                     // Static samplers are implemented in the frontend on
                     // D3D11.
                     DAWN_UNREACHABLE();
diff --git a/src/dawn/native/d3d12/BindGroupD3D12.cpp b/src/dawn/native/d3d12/BindGroupD3D12.cpp
index 3530beb..b019539 100644
--- a/src/dawn/native/d3d12/BindGroupD3D12.cpp
+++ b/src/dawn/native/d3d12/BindGroupD3D12.cpp
@@ -194,14 +194,14 @@
                         DAWN_UNREACHABLE();
                 }
             },
-            [](const StaticSamplerHolderBindingLayout&) {
+            [](const StaticSamplerBindingInfo&) {
                 // Static samplers are handled in the frontend.
                 // TODO(crbug.com/dawn/2483): Implement static samplers in the
                 // D3D12 backend.
                 DAWN_UNREACHABLE();
             },
             // No-op as samplers will be later initialized by CreateSamplers().
-            [](const SamplerBindingLayout&) {});
+            [](const SamplerBindingInfo&) {});
     }
 
     // Loop through the dynamic storage buffers and build a flat map from the index of the
diff --git a/src/dawn/native/d3d12/BindGroupLayoutD3D12.cpp b/src/dawn/native/d3d12/BindGroupLayoutD3D12.cpp
index ee1fb50..86c8fe3 100644
--- a/src/dawn/native/d3d12/BindGroupLayoutD3D12.cpp
+++ b/src/dawn/native/d3d12/BindGroupLayoutD3D12.cpp
@@ -53,14 +53,14 @@
                     DAWN_UNREACHABLE();
             }
         },
-        [](const StaticSamplerHolderBindingLayout&) -> D3D12_DESCRIPTOR_RANGE_TYPE {
+        [](const StaticSamplerBindingInfo&) -> D3D12_DESCRIPTOR_RANGE_TYPE {
             // Static samplers are handled in the frontend.
             // TODO(crbug.com/dawn/2483): Implement static samplers in the
             // D3D12 backend.
             DAWN_UNREACHABLE();
             return D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER;
         },
-        [](const SamplerBindingLayout&) -> D3D12_DESCRIPTOR_RANGE_TYPE {
+        [](const SamplerBindingInfo&) -> D3D12_DESCRIPTOR_RANGE_TYPE {
             return D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER;
         },
         [](const TextureBindingInfo&) -> D3D12_DESCRIPTOR_RANGE_TYPE {
@@ -127,14 +127,14 @@
         // don't need to set DESCRIPTORS_VOLATILE for any binding types.
         range.Flags = MatchVariant(
             bindingInfo.bindingLayout,
-            [](const StaticSamplerHolderBindingLayout&) -> D3D12_DESCRIPTOR_RANGE_FLAGS {
+            [](const StaticSamplerBindingInfo&) -> D3D12_DESCRIPTOR_RANGE_FLAGS {
                 // Static samplers are handled in the frontend.
                 // TODO(crbug.com/dawn/2483): Implement static samplers in the
                 // D3D12 backend.
                 DAWN_UNREACHABLE();
                 return D3D12_DESCRIPTOR_RANGE_FLAG_NONE;
             },
-            [](const SamplerBindingLayout&) -> D3D12_DESCRIPTOR_RANGE_FLAGS {
+            [](const SamplerBindingInfo&) -> D3D12_DESCRIPTOR_RANGE_FLAGS {
                 // Sampler descriptor ranges don't support DATA_* flags at all since samplers do not
                 // point to data.
                 return D3D12_DESCRIPTOR_RANGE_FLAG_NONE;
diff --git a/src/dawn/native/d3d12/SamplerHeapCacheD3D12.cpp b/src/dawn/native/d3d12/SamplerHeapCacheD3D12.cpp
index da7d4e2..188714a 100644
--- a/src/dawn/native/d3d12/SamplerHeapCacheD3D12.cpp
+++ b/src/dawn/native/d3d12/SamplerHeapCacheD3D12.cpp
@@ -120,7 +120,7 @@
     for (BindingIndex bindingIndex = bgl->GetDynamicBufferCount();
          bindingIndex < bgl->GetBindingCount(); ++bindingIndex) {
         const BindingInfo& bindingInfo = bgl->GetBindingInfo(bindingIndex);
-        if (std::holds_alternative<SamplerBindingLayout>(bindingInfo.bindingLayout)) {
+        if (std::holds_alternative<SamplerBindingInfo>(bindingInfo.bindingLayout)) {
             samplers.push_back(ToBackend(group->GetBindingAsSampler(bindingIndex)));
         }
     }
diff --git a/src/dawn/native/metal/CommandBufferMTL.mm b/src/dawn/native/metal/CommandBufferMTL.mm
index c722742..a3e992a 100644
--- a/src/dawn/native/metal/CommandBufferMTL.mm
+++ b/src/dawn/native/metal/CommandBufferMTL.mm
@@ -624,7 +624,7 @@
                                   withRange:NSMakeRange(computeIndex, 1)];
                     }
                 },
-                [&](const SamplerBindingLayout&) {
+                [&](const SamplerBindingInfo&) {
                     auto sampler = ToBackend(group->GetBindingAsSampler(bindingIndex));
                     if (hasVertStage) {
                         [render setVertexSamplerState:sampler->GetMTLSamplerState()
@@ -639,7 +639,7 @@
                                          atIndex:computeIndex];
                     }
                 },
-                [&](const StaticSamplerHolderBindingLayout&) {
+                [&](const StaticSamplerBindingInfo&) {
                     // Static samplers are handled in the frontend.
                     // TODO(crbug.com/dawn/2482): Implement static samplers in the
                     // Metal backend.
diff --git a/src/dawn/native/metal/PipelineLayoutMTL.mm b/src/dawn/native/metal/PipelineLayoutMTL.mm
index e710290..dde96cc 100644
--- a/src/dawn/native/metal/PipelineLayoutMTL.mm
+++ b/src/dawn/native/metal/PipelineLayoutMTL.mm
@@ -67,7 +67,7 @@
                         mIndexInfo[stage][group][bindingIndex] = bufferIndex;
                         bufferIndex++;
                     },
-                    [&](const SamplerBindingLayout&) {
+                    [&](const SamplerBindingInfo&) {
                         mIndexInfo[stage][group][bindingIndex] = samplerIndex;
                         samplerIndex++;
                     },
@@ -79,7 +79,7 @@
                         mIndexInfo[stage][group][bindingIndex] = textureIndex;
                         textureIndex++;
                     },
-                    [&](const StaticSamplerHolderBindingLayout&) {
+                    [&](const StaticSamplerBindingInfo&) {
                         // Static samplers are handled in the frontend.
                         // TODO(crbug.com/dawn/2482): Implement static samplers in the
                         // Metal backend.
diff --git a/src/dawn/native/opengl/CommandBufferGL.cpp b/src/dawn/native/opengl/CommandBufferGL.cpp
index 63b5fb8..4f9bb7e 100644
--- a/src/dawn/native/opengl/CommandBufferGL.cpp
+++ b/src/dawn/native/opengl/CommandBufferGL.cpp
@@ -318,10 +318,10 @@
 
                     gl.BindBufferRange(target, index, buffer, offset, binding.size);
                 },
-                [&](const StaticSamplerHolderBindingLayout& layout) {
+                [&](const StaticSamplerBindingInfo& layout) {
                     BindSamplerAtIndex(gl, layout.sampler.Get(), indices[bindingIndex]);
                 },
-                [&](const SamplerBindingLayout&) {
+                [&](const SamplerBindingInfo&) {
                     BindSamplerAtIndex(gl, group->GetBindingAsSampler(bindingIndex),
                                        indices[bindingIndex]);
                 },
diff --git a/src/dawn/native/opengl/PipelineLayoutGL.cpp b/src/dawn/native/opengl/PipelineLayoutGL.cpp
index 976356f..41a7e56 100644
--- a/src/dawn/native/opengl/PipelineLayoutGL.cpp
+++ b/src/dawn/native/opengl/PipelineLayoutGL.cpp
@@ -67,11 +67,11 @@
                             DAWN_UNREACHABLE();
                     }
                 },
-                [&](const StaticSamplerHolderBindingLayout&) {
+                [&](const StaticSamplerBindingInfo&) {
                     mIndexInfo[group][bindingIndex] = samplerIndex;
                     samplerIndex++;
                 },
-                [&](const SamplerBindingLayout&) {
+                [&](const SamplerBindingInfo&) {
                     mIndexInfo[group][bindingIndex] = samplerIndex;
                     samplerIndex++;
                 },
diff --git a/src/dawn/native/vulkan/BindGroupLayoutVk.cpp b/src/dawn/native/vulkan/BindGroupLayoutVk.cpp
index 603edbc..11de97a 100644
--- a/src/dawn/native/vulkan/BindGroupLayoutVk.cpp
+++ b/src/dawn/native/vulkan/BindGroupLayoutVk.cpp
@@ -85,8 +85,8 @@
                     return VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
             }
         },
-        [](const SamplerBindingLayout&) { return VK_DESCRIPTOR_TYPE_SAMPLER; },
-        [](const StaticSamplerHolderBindingLayout&) { return VK_DESCRIPTOR_TYPE_SAMPLER; },
+        [](const SamplerBindingInfo&) { return VK_DESCRIPTOR_TYPE_SAMPLER; },
+        [](const StaticSamplerBindingInfo&) { return VK_DESCRIPTOR_TYPE_SAMPLER; },
         [](const TextureBindingInfo&) { return VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; },
         [](const StorageTextureBindingInfo&) { return VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; });
 }
@@ -116,9 +116,8 @@
         vkBinding.descriptorCount = 1;
         vkBinding.stageFlags = VulkanShaderStageFlags(bindingInfo.visibility);
 
-        if (std::holds_alternative<StaticSamplerHolderBindingLayout>(bindingInfo.bindingLayout)) {
-            auto samplerLayout =
-                std::get<StaticSamplerHolderBindingLayout>(bindingInfo.bindingLayout);
+        if (std::holds_alternative<StaticSamplerBindingInfo>(bindingInfo.bindingLayout)) {
+            auto samplerLayout = std::get<StaticSamplerBindingInfo>(bindingInfo.bindingLayout);
             auto sampler = ToBackend(samplerLayout.sampler);
             vkBinding.pImmutableSamplers = &sampler->GetHandle().GetHandle();
         } else {
diff --git a/src/dawn/native/vulkan/BindGroupVk.cpp b/src/dawn/native/vulkan/BindGroupVk.cpp
index 8fc4af3..cd5b0ff 100644
--- a/src/dawn/native/vulkan/BindGroupVk.cpp
+++ b/src/dawn/native/vulkan/BindGroupVk.cpp
@@ -98,13 +98,13 @@
                 write.pBufferInfo = &writeBufferInfo[numWrites];
                 return true;
             },
-            [&](const SamplerBindingLayout&) -> bool {
+            [&](const SamplerBindingInfo&) -> bool {
                 Sampler* sampler = ToBackend(GetBindingAsSampler(bindingIndex));
                 writeImageInfo[numWrites].sampler = sampler->GetHandle();
                 write.pImageInfo = &writeImageInfo[numWrites];
                 return true;
             },
-            [&](const StaticSamplerHolderBindingLayout& layout) -> bool {
+            [&](const StaticSamplerBindingInfo& layout) -> bool {
                 // Static samplers are bound into the Vulkan layout as immutable
                 // samplers at BindGroupLayout creation time. There is no work
                 // to be done at BindGroup creation time.
diff --git a/src/dawn/native/webgpu_absl_format.cpp b/src/dawn/native/webgpu_absl_format.cpp
index 1bc3138..dfe7353 100644
--- a/src/dawn/native/webgpu_absl_format.cpp
+++ b/src/dawn/native/webgpu_absl_format.cpp
@@ -124,11 +124,11 @@
             s->Append(absl::StrFormat(*fmt, static_cast<uint32_t>(value.binding), value.visibility,
                                       BindingInfoType::Buffer, layout));
         },
-        [&](const SamplerBindingLayout& layout) {
+        [&](const SamplerBindingInfo& layout) {
             s->Append(absl::StrFormat(*fmt, static_cast<uint32_t>(value.binding), value.visibility,
                                       BindingInfoType::Sampler, layout));
         },
-        [&](const StaticSamplerHolderBindingLayout& layout) {
+        [&](const StaticSamplerBindingInfo& layout) {
             s->Append(absl::StrFormat(*fmt, static_cast<uint32_t>(value.binding), value.visibility,
                                       BindingInfoType::StaticSampler, layout));
         },
@@ -195,6 +195,30 @@
 }
 
 absl::FormatConvertResult<absl::FormatConversionCharSet::kString> AbslFormatConvert(
+    const SamplerBindingInfo& value,
+    const absl::FormatConversionSpec& spec,
+    absl::FormatSink* s) {
+    s->Append(absl::StrFormat("{type: %s}", value.type));
+    return {true};
+}
+
+absl::FormatConvertResult<absl::FormatConversionCharSet::kString> AbslFormatConvert(
+    const SamplerBindingLayout& value,
+    const absl::FormatConversionSpec& spec,
+    absl::FormatSink* s) {
+    SamplerBindingInfo info(value);
+    return AbslFormatConvert(info, spec, s);
+}
+
+absl::FormatConvertResult<absl::FormatConversionCharSet::kString> AbslFormatConvert(
+    const StaticSamplerBindingInfo& value,
+    const absl::FormatConversionSpec& spec,
+    absl::FormatSink* s) {
+    s->Append(absl::StrFormat("{sampler: %s}", value.sampler.Get()));
+    return {true};
+}
+
+absl::FormatConvertResult<absl::FormatConversionCharSet::kString> AbslFormatConvert(
     const ImageCopyTexture* value,
     const absl::FormatConversionSpec& spec,
     absl::FormatSink* s) {
@@ -237,15 +261,6 @@
     return {true};
 }
 
-absl::FormatConvertResult<absl::FormatConversionCharSet::kString> AbslFormatConvert(
-    const StaticSamplerHolderBindingLayout& value,
-    const absl::FormatConversionSpec& spec,
-    absl::FormatSink* s) {
-    s->Append(
-        absl::StrFormat("{type: StaticSamplerBindingLayout, sampler: %s}", value.sampler.Get()));
-    return {true};
-}
-
 //
 // Objects
 //
diff --git a/src/dawn/native/webgpu_absl_format.h b/src/dawn/native/webgpu_absl_format.h
index 619bdfd..c3dda1c 100644
--- a/src/dawn/native/webgpu_absl_format.h
+++ b/src/dawn/native/webgpu_absl_format.h
@@ -120,6 +120,24 @@
     const absl::FormatConversionSpec& spec,
     absl::FormatSink* s);
 
+struct SamplerBindingInfo;
+absl::FormatConvertResult<absl::FormatConversionCharSet::kString> AbslFormatConvert(
+    const SamplerBindingInfo& value,
+    const absl::FormatConversionSpec& spec,
+    absl::FormatSink* s);
+
+struct SamplerBindingLayout;
+absl::FormatConvertResult<absl::FormatConversionCharSet::kString> AbslFormatConvert(
+    const SamplerBindingLayout& value,
+    const absl::FormatConversionSpec& spec,
+    absl::FormatSink* s);
+
+struct StaticSamplerBindingInfo;
+absl::FormatConvertResult<absl::FormatConversionCharSet::kString> AbslFormatConvert(
+    const StaticSamplerBindingInfo& value,
+    const absl::FormatConversionSpec& spec,
+    absl::FormatSink* s);
+
 struct ImageCopyTexture;
 absl::FormatConvertResult<absl::FormatConversionCharSet::kString> AbslFormatConvert(
     const ImageCopyTexture* value,
@@ -138,12 +156,6 @@
     const absl::FormatConversionSpec& spec,
     absl::FormatSink* s);
 
-struct StaticSamplerHolderBindingLayout;
-absl::FormatConvertResult<absl::FormatConversionCharSet::kString> AbslFormatConvert(
-    const StaticSamplerHolderBindingLayout& value,
-    const absl::FormatConversionSpec& spec,
-    absl::FormatSink* s);
-
 //
 // Objects
 //