Use an internal version of TextureBindingLayout.

Bug: TBD
Change-Id: Ife5e2e847ab8b998bdb112a4ebfbc0785abf2073
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/182922
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/templates/dawn/native/api_absl_format.cpp b/generator/templates/dawn/native/api_absl_format.cpp
index 13c2b1c..2880e7a 100644
--- a/generator/templates/dawn/native/api_absl_format.cpp
+++ b/generator/templates/dawn/native/api_absl_format.cpp
@@ -79,7 +79,6 @@
     {% for type in by_category["structure"] %}
         {% if type.name.get() in [
              "sampler binding layout",
-             "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 6e5294d..5b98c7c 100644
--- a/generator/templates/dawn/native/api_absl_format.h
+++ b/generator/templates/dawn/native/api_absl_format.h
@@ -69,7 +69,6 @@
     {% for type in by_category["structure"] %}
         {% if type.name.get() in [
              "sampler binding layout",
-             "texture binding layout",
            ]
         %}
         absl::FormatConvertResult<absl::FormatConversionCharSet::kString>
diff --git a/src/dawn/native/BindGroup.cpp b/src/dawn/native/BindGroup.cpp
index 1c1fcaf..aea660c 100644
--- a/src/dawn/native/BindGroup.cpp
+++ b/src/dawn/native/BindGroup.cpp
@@ -149,7 +149,7 @@
 
 MaybeError ValidateSampledTextureBinding(DeviceBase* device,
                                          const BindGroupEntry& entry,
-                                         const TextureBindingLayout& layout,
+                                         const TextureBindingInfo& layout,
                                          UsageValidationMode mode) {
     DAWN_TRY(ValidateTextureBindGroupEntry(device, entry));
 
@@ -375,7 +375,7 @@
                                  i, layout);
                 return {};
             },
-            [&](const TextureBindingLayout& layout) -> MaybeError {
+            [&](const TextureBindingInfo& layout) -> MaybeError {
                 DAWN_TRY_CONTEXT(ValidateSampledTextureBinding(device, entry, layout, mode),
                                  "validating entries[%u] as a Sampled Texture."
                                  "\nExpected entry layout: %s",
@@ -589,7 +589,7 @@
     DAWN_ASSERT(!IsError());
     const BindGroupLayoutInternalBase* layout = GetLayout();
     DAWN_ASSERT(bindingIndex < layout->GetBindingCount());
-    DAWN_ASSERT(std::holds_alternative<TextureBindingLayout>(
+    DAWN_ASSERT(std::holds_alternative<TextureBindingInfo>(
                     layout->GetBindingInfo(bindingIndex).bindingLayout) ||
                 std::holds_alternative<StorageTextureBindingInfo>(
                     layout->GetBindingInfo(bindingIndex).bindingLayout));
diff --git a/src/dawn/native/BindGroupLayoutInternal.cpp b/src/dawn/native/BindGroupLayoutInternal.cpp
index 35379a1..52ed614 100644
--- a/src/dawn/native/BindGroupLayoutInternal.cpp
+++ b/src/dawn/native/BindGroupLayoutInternal.cpp
@@ -361,8 +361,8 @@
                 std::get<StaticSamplerHolderBindingLayout>(b.bindingLayout);
             return layoutA.sampler != layoutB.sampler;
         },
-        [&](const TextureBindingLayout& layoutA) -> bool {
-            const TextureBindingLayout& layoutB = std::get<TextureBindingLayout>(b.bindingLayout);
+        [&](const TextureBindingInfo& layoutA) -> bool {
+            const TextureBindingInfo& layoutB = std::get<TextureBindingInfo>(b.bindingLayout);
             return layoutA.sampleType != layoutB.sampleType ||
                    layoutA.viewDimension != layoutB.viewDimension ||
                    layoutA.multisampled != layoutB.multisampled;
@@ -401,7 +401,7 @@
         if (binding->texture.viewDimension == wgpu::TextureViewDimension::Undefined) {
             bindingLayout.viewDimension = wgpu::TextureViewDimension::e2D;
         }
-        bindingInfo.bindingLayout = bindingLayout;
+        bindingInfo.bindingLayout = TextureBindingInfo(bindingLayout);
     } else if (binding->storageTexture.access != wgpu::StorageTextureAccess::Undefined) {
         StorageTextureBindingLayout bindingLayout =
             binding->storageTexture.WithTrivialFrontendDefaults();
@@ -484,8 +484,8 @@
             break;
         }
         case BindingInfoType::Texture: {
-            const auto& aLayout = std::get<TextureBindingLayout>(aInfo.bindingLayout);
-            const auto& bLayout = std::get<TextureBindingLayout>(bInfo.bindingLayout);
+            const auto& aLayout = std::get<TextureBindingInfo>(aInfo.bindingLayout);
+            const auto& bLayout = std::get<TextureBindingInfo>(bInfo.bindingLayout);
             if (aLayout.multisampled != bLayout.multisampled) {
                 return aLayout.multisampled < bLayout.multisampled;
             }
@@ -640,7 +640,7 @@
             [&](const SamplerBindingLayout& layout) {
                 recorder.Record(BindingInfoType::Sampler, layout.type);
             },
-            [&](const TextureBindingLayout& layout) {
+            [&](const TextureBindingInfo& layout) {
                 recorder.Record(BindingInfoType::Texture, layout.sampleType, layout.viewDimension,
                                 layout.multisampled);
             },
diff --git a/src/dawn/native/BindingInfo.cpp b/src/dawn/native/BindingInfo.cpp
index 582598f..c7325e6 100644
--- a/src/dawn/native/BindingInfo.cpp
+++ b/src/dawn/native/BindingInfo.cpp
@@ -38,7 +38,7 @@
         info.bindingLayout,
         [](const BufferBindingInfo&) -> BindingInfoType { return BindingInfoType::Buffer; },
         [](const SamplerBindingLayout&) -> BindingInfoType { return BindingInfoType::Sampler; },
-        [](const TextureBindingLayout&) -> BindingInfoType { return BindingInfoType::Texture; },
+        [](const TextureBindingInfo&) -> BindingInfoType { return BindingInfoType::Texture; },
         [](const StorageTextureBindingInfo&) -> BindingInfoType {
             return BindingInfoType::StorageTexture;
         },
@@ -237,4 +237,11 @@
 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) {}
 }  // namespace dawn::native
diff --git a/src/dawn/native/BindingInfo.h b/src/dawn/native/BindingInfo.h
index a4c941e..87d8a26 100644
--- a/src/dawn/native/BindingInfo.h
+++ b/src/dawn/native/BindingInfo.h
@@ -82,6 +82,18 @@
     bool hasDynamicOffset = false;
 };
 
+// A mirror of wgpu::TextureBindingLayout for use inside dawn::native.
+struct TextureBindingInfo {
+    TextureBindingInfo();
+    explicit TextureBindingInfo(const TextureBindingLayout& apiLayout);
+
+    // For shader reflection UnfilterableFloat is never used and the sample type is Float for any
+    // texture_Nd<f32>.
+    wgpu::TextureSampleType sampleType;
+    wgpu::TextureViewDimension viewDimension;
+    bool multisampled;
+};
+
 // A mirror of wgpu::StorageTextureBindingLayout for use inside dawn::native.
 struct StorageTextureBindingInfo {
     StorageTextureBindingInfo();
@@ -92,13 +104,16 @@
     wgpu::StorageTextureAccess access;
 };
 
+// A mirror of wgpu::ExternalTextureBindingLayout for use inside dawn::native.
+struct ExternalTextureBindingInfo {};
+
 struct BindingInfo {
     BindingNumber binding;
     wgpu::ShaderStage visibility;
 
     std::variant<BufferBindingInfo,
                  SamplerBindingLayout,
-                 TextureBindingLayout,
+                 TextureBindingInfo,
                  StorageTextureBindingInfo,
                  StaticSamplerHolderBindingLayout>
         bindingLayout;
diff --git a/src/dawn/native/CommandBufferStateTracker.cpp b/src/dawn/native/CommandBufferStateTracker.cpp
index 5b94e78..4ee8e11 100644
--- a/src/dawn/native/CommandBufferStateTracker.cpp
+++ b/src/dawn/native/CommandBufferStateTracker.cpp
@@ -361,7 +361,7 @@
 
         for (BindingIndex bindingIndex{0}; bindingIndex < bgl->GetBindingCount(); ++bindingIndex) {
             const BindingInfo& bindingInfo = bgl->GetBindingInfo(bindingIndex);
-            if (!std::holds_alternative<TextureBindingLayout>(bindingInfo.bindingLayout) &&
+            if (!std::holds_alternative<TextureBindingInfo>(bindingInfo.bindingLayout) &&
                 !std::holds_alternative<StorageTextureBindingInfo>(bindingInfo.bindingLayout)) {
                 continue;
             }
diff --git a/src/dawn/native/PassResourceUsageTracker.cpp b/src/dawn/native/PassResourceUsageTracker.cpp
index 71fb8da..1b65869 100644
--- a/src/dawn/native/PassResourceUsageTracker.cpp
+++ b/src/dawn/native/PassResourceUsageTracker.cpp
@@ -130,7 +130,7 @@
                         DAWN_UNREACHABLE();
                 }
             },
-            [&](const TextureBindingLayout& layout) {
+            [&](const TextureBindingInfo& layout) {
                 TextureViewBase* view = group->GetBindingAsTextureView(bindingIndex);
                 switch (layout.sampleType) {
                     case kInternalResolveAttachmentSampleType:
@@ -218,7 +218,7 @@
             [&](const BufferBindingInfo&) {
                 mUsage.referencedBuffers.insert(group->GetBindingAsBufferBinding(index).buffer);
             },
-            [&](const TextureBindingLayout&) {
+            [&](const TextureBindingInfo&) {
                 mUsage.referencedTextures.insert(
                     group->GetBindingAsTextureView(index)->GetTexture());
             },
diff --git a/src/dawn/native/PipelineLayout.cpp b/src/dawn/native/PipelineLayout.cpp
index 170ac7b..dcc6b6f 100644
--- a/src/dawn/native/PipelineLayout.cpp
+++ b/src/dawn/native/PipelineLayout.cpp
@@ -247,34 +247,16 @@
                     entry.sampler.type = wgpu::SamplerBindingType::Filtering;
                 }
             },
-            [&](const SampledTextureBindingInfo& bindingInfo) {
-                switch (bindingInfo.compatibleSampleTypes) {
-                    case SampleTypeBit::Depth:
-                        entry.texture.sampleType = wgpu::TextureSampleType::Depth;
-                        break;
-                    case SampleTypeBit::Sint:
-                        entry.texture.sampleType = wgpu::TextureSampleType::Sint;
-                        break;
-                    case SampleTypeBit::Uint:
-                        entry.texture.sampleType = wgpu::TextureSampleType::Uint;
-                        break;
-                    case SampleTypeBit::Float:
-                    case SampleTypeBit::UnfilterableFloat:
-                    case SampleTypeBit::None:
-                        DAWN_UNREACHABLE();
-                        break;
-                    default:
-                        if (bindingInfo.compatibleSampleTypes ==
-                            (SampleTypeBit::Float | SampleTypeBit::UnfilterableFloat)) {
-                            // Default to UnfilterableFloat. It will be promoted to Float
-                            // if it is used with a sampler.
-                            entry.texture.sampleType = wgpu::TextureSampleType::UnfilterableFloat;
-                        } else {
-                            DAWN_UNREACHABLE();
-                        }
-                }
+            [&](const TextureBindingInfo& bindingInfo) {
+                entry.texture.sampleType = bindingInfo.sampleType;
                 entry.texture.viewDimension = bindingInfo.viewDimension;
                 entry.texture.multisampled = bindingInfo.multisampled;
+
+                // Default to UnfilterableFloat for texture_Nd<f32> as it will be promoted to Float
+                // if it is used with a sampler.
+                if (entry.texture.sampleType == wgpu::TextureSampleType::Float) {
+                    entry.texture.sampleType = wgpu::TextureSampleType::UnfilterableFloat;
+                }
             },
             [&](const StorageTextureBindingInfo& bindingInfo) {
                 entry.storageTexture.access = bindingInfo.access;
diff --git a/src/dawn/native/ShaderModule.cpp b/src/dawn/native/ShaderModule.cpp
index 2450591..4e27d07 100644
--- a/src/dawn/native/ShaderModule.cpp
+++ b/src/dawn/native/ShaderModule.cpp
@@ -166,16 +166,18 @@
     DAWN_UNREACHABLE();
 }
 
-SampleTypeBit TintSampledKindToSampleTypeBit(tint::inspector::ResourceBinding::SampledKind s) {
+wgpu::TextureSampleType TintSampledKindToSampleType(
+    tint::inspector::ResourceBinding::SampledKind s) {
     switch (s) {
         case tint::inspector::ResourceBinding::SampledKind::kSInt:
-            return SampleTypeBit::Sint;
+            return wgpu::TextureSampleType::Sint;
         case tint::inspector::ResourceBinding::SampledKind::kUInt:
-            return SampleTypeBit::Uint;
+            return wgpu::TextureSampleType::Uint;
         case tint::inspector::ResourceBinding::SampledKind::kFloat:
-            return SampleTypeBit::Float | SampleTypeBit::UnfilterableFloat;
+            // Note that Float is compatible with both Float and UnfilterableFloat.
+            return wgpu::TextureSampleType::Float;
         case tint::inspector::ResourceBinding::SampledKind::kUnknown:
-            return SampleTypeBit::None;
+            return wgpu::TextureSampleType::Undefined;
     }
     DAWN_UNREACHABLE();
 }
@@ -429,7 +431,7 @@
     return MatchVariant(
         shaderInfo.bindingInfo, [](const BufferBindingInfo&) { return BindingInfoType::Buffer; },
         [](const SamplerBindingInfo&) { return BindingInfoType::Sampler; },
-        [](const SampledTextureBindingInfo&) { return BindingInfoType::Texture; },
+        [](const TextureBindingInfo&) { return BindingInfoType::Texture; },
         [](const StorageTextureBindingInfo&) { return BindingInfoType::StorageTexture; },
         [](const ExternalTextureBindingInfo&) { return BindingInfoType::ExternalTexture; });
 }
@@ -493,33 +495,31 @@
 
     return MatchVariant(
         shaderInfo.bindingInfo,
-        [&](const SampledTextureBindingInfo& bindingInfo) -> MaybeError {
-            const TextureBindingLayout& bindingLayout =
-                std::get<TextureBindingLayout>(layoutInfo.bindingLayout);
+        [&](const TextureBindingInfo& bindingInfo) -> MaybeError {
+            const TextureBindingInfo& bindingLayout =
+                std::get<TextureBindingInfo>(layoutInfo.bindingLayout);
             DAWN_INVALID_IF(
                 bindingLayout.multisampled != bindingInfo.multisampled,
                 "Binding multisampled flag (%u) doesn't match the layout's multisampled "
                 "flag (%u)",
                 bindingLayout.multisampled, bindingInfo.multisampled);
 
-            // TODO(dawn:563): Provide info about the sample types.
-            SampleTypeBit requiredType;
-            if (bindingLayout.sampleType == kInternalResolveAttachmentSampleType) {
-                // If the layout's texture's sample type is
-                // kInternalResolveAttachmentSampleType, then the shader's compatible sample
-                // types must contain float.
-                requiredType = SampleTypeBit::UnfilterableFloat;
-            } else {
-                requiredType = SampleTypeToSampleTypeBit(bindingLayout.sampleType);
+            wgpu::TextureSampleType requiredShaderType = bindingLayout.sampleType;
+            // Both UnfilterableFloat and kInternalResolveAttachmentSampleType are compatible with
+            // texture_Nd<f32> instead of having a specific WGSL type.
+            if (requiredShaderType == kInternalResolveAttachmentSampleType ||
+                requiredShaderType == wgpu::TextureSampleType::UnfilterableFloat) {
+                requiredShaderType = wgpu::TextureSampleType::Float;
             }
-
-            DAWN_INVALID_IF(!(bindingInfo.compatibleSampleTypes & requiredType),
-                            "The sample type in the shader is not compatible with the "
-                            "sample type of the layout.");
+            DAWN_INVALID_IF(bindingInfo.sampleType != requiredShaderType,
+                            "The shader's texture sample type (%s) isn't compatible with the "
+                            "layout's texture sample type (%s) (it is only compatible with %s for "
+                            "the shader texture sample type).",
+                            bindingInfo.sampleType, bindingLayout.sampleType, requiredShaderType);
 
             DAWN_INVALID_IF(
                 bindingLayout.viewDimension != bindingInfo.viewDimension,
-                "The shader's binding dimension (%s) doesn't match the shader's binding "
+                "The shader's binding dimension (%s) doesn't match the layout's binding "
                 "dimension (%s).",
                 bindingLayout.viewDimension, bindingInfo.viewDimension);
             return {};
@@ -875,17 +875,16 @@
             }
 
             case BindingInfoType::Texture: {
-                SampledTextureBindingInfo bindingInfo = {};
+                TextureBindingInfo bindingInfo = {};
                 bindingInfo.viewDimension =
                     TintTextureDimensionToTextureViewDimension(resource.dim);
                 if (resource.resource_type ==
                         tint::inspector::ResourceBinding::ResourceType::kDepthTexture ||
                     resource.resource_type ==
                         tint::inspector::ResourceBinding::ResourceType::kDepthMultisampledTexture) {
-                    bindingInfo.compatibleSampleTypes = SampleTypeBit::Depth;
+                    bindingInfo.sampleType = wgpu::TextureSampleType::Depth;
                 } else {
-                    bindingInfo.compatibleSampleTypes =
-                        TintSampledKindToSampleTypeBit(resource.sampled_kind);
+                    bindingInfo.sampleType = TintSampledKindToSampleType(resource.sampled_kind);
                 }
                 bindingInfo.multisampled =
                     resource.resource_type ==
@@ -1191,8 +1190,8 @@
             layout->GetBindGroupLayout(pair.texture.group);
         const BindingInfo& textureInfo =
             textureBGL->GetBindingInfo(textureBGL->GetBindingIndex(pair.texture.binding));
-        const TextureBindingLayout& sampledTextureBindingLayout =
-            std::get<TextureBindingLayout>(textureInfo.bindingLayout);
+        const TextureBindingInfo& sampledTextureBindingInfo =
+            std::get<TextureBindingInfo>(textureInfo.bindingLayout);
 
         // Uint/Sint can't be statically used with a sampler, so they any
         // texture bindings reflected must be float or depth textures. If
@@ -1200,12 +1199,12 @@
         // specifies a uint/sint texture binding,
         // |ValidateCompatibilityWithBindGroupLayout| will fail since the
         // sampleType does not match.
-        DAWN_ASSERT(sampledTextureBindingLayout.sampleType != wgpu::TextureSampleType::Undefined &&
-                    sampledTextureBindingLayout.sampleType != wgpu::TextureSampleType::Uint &&
-                    sampledTextureBindingLayout.sampleType != wgpu::TextureSampleType::Sint);
+        DAWN_ASSERT(sampledTextureBindingInfo.sampleType != wgpu::TextureSampleType::Undefined &&
+                    sampledTextureBindingInfo.sampleType != wgpu::TextureSampleType::Uint &&
+                    sampledTextureBindingInfo.sampleType != wgpu::TextureSampleType::Sint);
 
         DAWN_INVALID_IF(
-            sampledTextureBindingLayout.sampleType == wgpu::TextureSampleType::UnfilterableFloat,
+            sampledTextureBindingInfo.sampleType == wgpu::TextureSampleType::UnfilterableFloat,
             "Texture binding (group:%u, binding:%u) is %s but used statically with a sampler "
             "(group:%u, binding:%u) that's %s",
             pair.texture.group, pair.texture.binding, wgpu::TextureSampleType::UnfilterableFloat,
diff --git a/src/dawn/native/ShaderModule.h b/src/dawn/native/ShaderModule.h
index e61e825..82974432 100644
--- a/src/dawn/native/ShaderModule.h
+++ b/src/dawn/native/ShaderModule.h
@@ -161,17 +161,6 @@
     bool isComparison;
 };
 
-// Mirrors wgpu::TextureBindingLayout but instead has a set of compatible sampleTypes
-// instead of a single enum.
-struct SampledTextureBindingInfo {
-    SampleTypeBit compatibleSampleTypes;
-    wgpu::TextureViewDimension viewDimension;
-    bool multisampled;
-};
-
-// Mirrors wgpu::ExternalTextureBindingLayout
-struct ExternalTextureBindingInfo {};
-
 // Per-binding shader metadata contains some SPIRV specific information in addition to
 // most of the frontend per-binding information.
 struct ShaderBindingInfo {
@@ -186,7 +175,7 @@
 
     std::variant<BufferBindingInfo,
                  SamplerBindingInfo,
-                 SampledTextureBindingInfo,
+                 TextureBindingInfo,
                  StorageTextureBindingInfo,
                  ExternalTextureBindingInfo>
         bindingInfo;
diff --git a/src/dawn/native/d3d11/BindGroupTrackerD3D11.cpp b/src/dawn/native/d3d11/BindGroupTrackerD3D11.cpp
index 7a10897..319c432 100644
--- a/src/dawn/native/d3d11/BindGroupTrackerD3D11.cpp
+++ b/src/dawn/native/d3d11/BindGroupTrackerD3D11.cpp
@@ -227,7 +227,7 @@
                         }
                         return {};
                     },
-                    [](const TextureBindingLayout&) -> MaybeError { return {}; },
+                    [](const TextureBindingInfo&) -> MaybeError { return {}; },
                     [](const SamplerBindingLayout&) -> MaybeError { return {}; },
                     [](const StaticSamplerHolderBindingLayout&) -> MaybeError {
                         // Static samplers are implemented in the frontend on
@@ -394,7 +394,7 @@
                 }
                 return {};
             },
-            [&](const TextureBindingLayout&) -> MaybeError {
+            [&](const TextureBindingInfo&) -> MaybeError {
                 TextureView* view = ToBackend(group->GetBindingAsTextureView(bindingIndex));
                 ComPtr<ID3D11ShaderResourceView> srv;
                 // For sampling from stencil, we have to use an internal mirror 'R8Uint' texture.
@@ -534,7 +534,7 @@
                     deviceContext->CSSetSamplers(bindingSlot, 1, &nullSampler);
                 }
             },
-            [&](const TextureBindingLayout&) {
+            [&](const TextureBindingInfo&) {
                 ID3D11ShaderResourceView* nullSRV = nullptr;
                 if (bindingVisibility & wgpu::ShaderStage::Vertex) {
                     deviceContext->VSSetShaderResources(bindingSlot, 1, &nullSRV);
diff --git a/src/dawn/native/d3d11/PipelineLayoutD3D11.cpp b/src/dawn/native/d3d11/PipelineLayoutD3D11.cpp
index a1243b3..5490a3c 100644
--- a/src/dawn/native/d3d11/PipelineLayoutD3D11.cpp
+++ b/src/dawn/native/d3d11/PipelineLayoutD3D11.cpp
@@ -89,7 +89,7 @@
                     // D3D11.
                     DAWN_UNREACHABLE();
                 },
-                [&](const TextureBindingLayout&) {
+                [&](const TextureBindingInfo&) {
                     mIndexInfo[group][bindingIndex] = shaderResourceViewIndex++;
                 },
                 [&](const StorageTextureBindingInfo& layout) {
diff --git a/src/dawn/native/d3d11/ShaderModuleD3D11.cpp b/src/dawn/native/d3d11/ShaderModuleD3D11.cpp
index 6ab1873..6d4ee66 100644
--- a/src/dawn/native/d3d11/ShaderModuleD3D11.cpp
+++ b/src/dawn/native/d3d11/ShaderModuleD3D11.cpp
@@ -151,8 +151,7 @@
                 bindings.sampler.emplace(
                     srcBindingPoint, tint::hlsl::writer::binding::Sampler{dstBindingPoint.group,
                                                                           dstBindingPoint.binding});
-            } else if (std::holds_alternative<SampledTextureBindingInfo>(
-                           shaderBindingInfo.bindingInfo)) {
+            } else if (std::holds_alternative<TextureBindingInfo>(shaderBindingInfo.bindingInfo)) {
                 bindings.texture.emplace(
                     srcBindingPoint, tint::hlsl::writer::binding::Texture{dstBindingPoint.group,
                                                                           dstBindingPoint.binding});
diff --git a/src/dawn/native/d3d12/BindGroupD3D12.cpp b/src/dawn/native/d3d12/BindGroupD3D12.cpp
index 991ef64..3530beb 100644
--- a/src/dawn/native/d3d12/BindGroupD3D12.cpp
+++ b/src/dawn/native/d3d12/BindGroupD3D12.cpp
@@ -144,7 +144,7 @@
                         DAWN_UNREACHABLE();
                 }
             },
-            [&](const TextureBindingLayout&) {
+            [&](const TextureBindingInfo&) {
                 auto* view = ToBackend(GetBindingAsTextureView(bindingIndex));
                 auto& srv = view->GetSRVDescriptor();
 
diff --git a/src/dawn/native/d3d12/BindGroupLayoutD3D12.cpp b/src/dawn/native/d3d12/BindGroupLayoutD3D12.cpp
index fa3a26e..ee1fb50 100644
--- a/src/dawn/native/d3d12/BindGroupLayoutD3D12.cpp
+++ b/src/dawn/native/d3d12/BindGroupLayoutD3D12.cpp
@@ -63,7 +63,7 @@
         [](const SamplerBindingLayout&) -> D3D12_DESCRIPTOR_RANGE_TYPE {
             return D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER;
         },
-        [](const TextureBindingLayout&) -> D3D12_DESCRIPTOR_RANGE_TYPE {
+        [](const TextureBindingInfo&) -> D3D12_DESCRIPTOR_RANGE_TYPE {
             return D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
         },
         [](const StorageTextureBindingInfo& layout) -> D3D12_DESCRIPTOR_RANGE_TYPE {
@@ -151,7 +151,7 @@
                 return D3D12_DESCRIPTOR_RANGE_FLAG_DESCRIPTORS_STATIC_KEEPING_BUFFER_BOUNDS_CHECKS |
                        D3D12_DESCRIPTOR_RANGE_FLAG_DATA_VOLATILE;
             },
-            [](const TextureBindingLayout&) -> D3D12_DESCRIPTOR_RANGE_FLAGS {
+            [](const TextureBindingInfo&) -> D3D12_DESCRIPTOR_RANGE_FLAGS {
                 return D3D12_DESCRIPTOR_RANGE_FLAG_DATA_VOLATILE;
             },
             [](const StorageTextureBindingInfo&) -> D3D12_DESCRIPTOR_RANGE_FLAGS {
diff --git a/src/dawn/native/d3d12/ShaderModuleD3D12.cpp b/src/dawn/native/d3d12/ShaderModuleD3D12.cpp
index bc04f3c..d9c48e8 100644
--- a/src/dawn/native/d3d12/ShaderModuleD3D12.cpp
+++ b/src/dawn/native/d3d12/ShaderModuleD3D12.cpp
@@ -227,8 +227,7 @@
                 bindings.sampler.emplace(
                     srcBindingPoint, tint::hlsl::writer::binding::Sampler{dstBindingPoint.group,
                                                                           dstBindingPoint.binding});
-            } else if (std::holds_alternative<SampledTextureBindingInfo>(
-                           shaderBindingInfo.bindingInfo)) {
+            } else if (std::holds_alternative<TextureBindingInfo>(shaderBindingInfo.bindingInfo)) {
                 bindings.texture.emplace(
                     srcBindingPoint, tint::hlsl::writer::binding::Texture{dstBindingPoint.group,
                                                                           dstBindingPoint.binding});
diff --git a/src/dawn/native/metal/CommandBufferMTL.mm b/src/dawn/native/metal/CommandBufferMTL.mm
index 849df19..46d8ee2 100644
--- a/src/dawn/native/metal/CommandBufferMTL.mm
+++ b/src/dawn/native/metal/CommandBufferMTL.mm
@@ -630,7 +630,7 @@
                     // Metal backend.
                     DAWN_UNREACHABLE();
                 },
-                [&](const TextureBindingLayout&) {
+                [&](const TextureBindingInfo&) {
                     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 0873b2d..e710290 100644
--- a/src/dawn/native/metal/PipelineLayoutMTL.mm
+++ b/src/dawn/native/metal/PipelineLayoutMTL.mm
@@ -71,7 +71,7 @@
                         mIndexInfo[stage][group][bindingIndex] = samplerIndex;
                         samplerIndex++;
                     },
-                    [&](const TextureBindingLayout&) {
+                    [&](const TextureBindingInfo&) {
                         mIndexInfo[stage][group][bindingIndex] = textureIndex;
                         textureIndex++;
                     },
diff --git a/src/dawn/native/metal/ShaderModuleMTL.mm b/src/dawn/native/metal/ShaderModuleMTL.mm
index 02004cb..1782553 100644
--- a/src/dawn/native/metal/ShaderModuleMTL.mm
+++ b/src/dawn/native/metal/ShaderModuleMTL.mm
@@ -178,7 +178,7 @@
                     bindings.sampler.emplace(srcBindingPoint, tint::msl::writer::binding::Sampler{
                                                                   dstBindingPoint.binding});
                 },
-                [&](const SampledTextureBindingInfo& bindingInfo) {
+                [&](const TextureBindingInfo& bindingInfo) {
                     bindings.texture.emplace(srcBindingPoint, tint::msl::writer::binding::Texture{
                                                                   dstBindingPoint.binding});
                 },
diff --git a/src/dawn/native/opengl/CommandBufferGL.cpp b/src/dawn/native/opengl/CommandBufferGL.cpp
index 554ce2d..057d36d 100644
--- a/src/dawn/native/opengl/CommandBufferGL.cpp
+++ b/src/dawn/native/opengl/CommandBufferGL.cpp
@@ -284,7 +284,7 @@
              ++bindingIndex) {
             const BindingInfo& bindingInfo = group->GetLayout()->GetBindingInfo(bindingIndex);
 
-            if (std::holds_alternative<TextureBindingLayout>(bindingInfo.bindingLayout)) {
+            if (std::holds_alternative<TextureBindingInfo>(bindingInfo.bindingLayout)) {
                 TextureView* view = ToBackend(group->GetBindingAsTextureView(bindingIndex));
                 view->CopyIfNeeded();
             }
@@ -329,7 +329,7 @@
                     BindSamplerAtIndex(gl, group->GetBindingAsSampler(bindingIndex),
                                        indices[bindingIndex]);
                 },
-                [&](const TextureBindingLayout&) {
+                [&](const TextureBindingInfo&) {
                     TextureView* view = ToBackend(group->GetBindingAsTextureView(bindingIndex));
                     GLuint handle = view->GetHandle();
                     GLenum target = view->GetGLTarget();
diff --git a/src/dawn/native/opengl/PipelineGL.cpp b/src/dawn/native/opengl/PipelineGL.cpp
index 5c665a2..2ca43fe 100644
--- a/src/dawn/native/opengl/PipelineGL.cpp
+++ b/src/dawn/native/opengl/PipelineGL.cpp
@@ -151,7 +151,7 @@
             mUnitsForTextures[textureIndex].push_back(textureUnit);
 
             const auto& bindingLayout = bgl->GetBindingInfo(bindingIndex).bindingLayout;
-            shouldUseFiltering = std::get<TextureBindingLayout>(bindingLayout).sampleType ==
+            shouldUseFiltering = std::get<TextureBindingInfo>(bindingLayout).sampleType ==
                                  wgpu::TextureSampleType::Float;
         }
         {
diff --git a/src/dawn/native/opengl/PipelineLayoutGL.cpp b/src/dawn/native/opengl/PipelineLayoutGL.cpp
index 9486d38..976356f 100644
--- a/src/dawn/native/opengl/PipelineLayoutGL.cpp
+++ b/src/dawn/native/opengl/PipelineLayoutGL.cpp
@@ -75,7 +75,7 @@
                     mIndexInfo[group][bindingIndex] = samplerIndex;
                     samplerIndex++;
                 },
-                [&](const TextureBindingLayout&) {
+                [&](const TextureBindingInfo&) {
                     mIndexInfo[group][bindingIndex] = sampledTextureIndex;
                     sampledTextureIndex++;
                 },
diff --git a/src/dawn/native/vulkan/BindGroupLayoutVk.cpp b/src/dawn/native/vulkan/BindGroupLayoutVk.cpp
index 7918c24..603edbc 100644
--- a/src/dawn/native/vulkan/BindGroupLayoutVk.cpp
+++ b/src/dawn/native/vulkan/BindGroupLayoutVk.cpp
@@ -87,7 +87,7 @@
         },
         [](const SamplerBindingLayout&) { return VK_DESCRIPTOR_TYPE_SAMPLER; },
         [](const StaticSamplerHolderBindingLayout&) { return VK_DESCRIPTOR_TYPE_SAMPLER; },
-        [](const TextureBindingLayout&) { return VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; },
+        [](const TextureBindingInfo&) { return VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; },
         [](const StorageTextureBindingInfo&) { return VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; });
 }
 
diff --git a/src/dawn/native/vulkan/BindGroupVk.cpp b/src/dawn/native/vulkan/BindGroupVk.cpp
index 2388de1..8fc4af3 100644
--- a/src/dawn/native/vulkan/BindGroupVk.cpp
+++ b/src/dawn/native/vulkan/BindGroupVk.cpp
@@ -110,7 +110,7 @@
                 // to be done at BindGroup creation time.
                 return false;
             },
-            [&](const TextureBindingLayout&) -> bool {
+            [&](const TextureBindingInfo&) -> bool {
                 TextureView* view = ToBackend(GetBindingAsTextureView(bindingIndex));
 
                 VkImageView handle = view->GetHandle();
diff --git a/src/dawn/native/vulkan/ShaderModuleVk.cpp b/src/dawn/native/vulkan/ShaderModuleVk.cpp
index d28e259..a04461e 100644
--- a/src/dawn/native/vulkan/ShaderModuleVk.cpp
+++ b/src/dawn/native/vulkan/ShaderModuleVk.cpp
@@ -278,7 +278,7 @@
                                              tint::spirv::writer::binding::Sampler{
                                                  dstBindingPoint.group, dstBindingPoint.binding});
                 },
-                [&](const SampledTextureBindingInfo& bindingInfo) {
+                [&](const TextureBindingInfo& bindingInfo) {
                     bindings.texture.emplace(srcBindingPoint,
                                              tint::spirv::writer::binding::Texture{
                                                  dstBindingPoint.group, dstBindingPoint.binding});
diff --git a/src/dawn/native/webgpu_absl_format.cpp b/src/dawn/native/webgpu_absl_format.cpp
index c069d88..c8f67e5 100644
--- a/src/dawn/native/webgpu_absl_format.cpp
+++ b/src/dawn/native/webgpu_absl_format.cpp
@@ -131,7 +131,7 @@
             s->Append(absl::StrFormat(*fmt, static_cast<uint32_t>(value.binding), value.visibility,
                                       BindingInfoType::StaticSampler, layout));
         },
-        [&](const TextureBindingLayout& layout) {
+        [&](const TextureBindingInfo& layout) {
             s->Append(absl::StrFormat(*fmt, static_cast<uint32_t>(value.binding), value.visibility,
                                       BindingInfoType::Texture, layout));
         },
@@ -160,6 +160,23 @@
 }
 
 absl::FormatConvertResult<absl::FormatConversionCharSet::kString> AbslFormatConvert(
+    const TextureBindingInfo& value,
+    const absl::FormatConversionSpec& spec,
+    absl::FormatSink* s) {
+    s->Append(absl::StrFormat("{sampleType: %s, viewDimension: %u, multisampled: %u}",
+                              value.sampleType, value.viewDimension, value.multisampled));
+    return {true};
+}
+
+absl::FormatConvertResult<absl::FormatConversionCharSet::kString> AbslFormatConvert(
+    const TextureBindingLayout& value,
+    const absl::FormatConversionSpec& spec,
+    absl::FormatSink* s) {
+    TextureBindingInfo info(value);
+    return AbslFormatConvert(info, spec, s);
+}
+
+absl::FormatConvertResult<absl::FormatConversionCharSet::kString> AbslFormatConvert(
     const StorageTextureBindingInfo& 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 a8656af..d98e088 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 TextureBindingInfo;
+absl::FormatConvertResult<absl::FormatConversionCharSet::kString> AbslFormatConvert(
+    const TextureBindingInfo& value,
+    const absl::FormatConversionSpec& spec,
+    absl::FormatSink* s);
+
+struct TextureBindingLayout;
+absl::FormatConvertResult<absl::FormatConversionCharSet::kString> AbslFormatConvert(
+    const TextureBindingLayout& value,
+    const absl::FormatConversionSpec& spec,
+    absl::FormatSink* s);
+
 struct StorageTextureBindingInfo;
 absl::FormatConvertResult<absl::FormatConversionCharSet::kString> AbslFormatConvert(
     const StorageTextureBindingInfo& value,
diff --git a/src/dawn/tests/white_box/InternalResolveAttachmentSampleTypeTests.cpp b/src/dawn/tests/white_box/InternalResolveAttachmentSampleTypeTests.cpp
index 4752e11..b490370 100644
--- a/src/dawn/tests/white_box/InternalResolveAttachmentSampleTypeTests.cpp
+++ b/src/dawn/tests/white_box/InternalResolveAttachmentSampleTypeTests.cpp
@@ -143,7 +143,7 @@
     pipelineDescriptor.layout = CreatePipelineLayout(/*withSampler=*/false);
 
     ASSERT_DEVICE_ERROR_MSG(device.CreateRenderPipeline(&pipelineDescriptor),
-                            testing::HasSubstr("not compatible"));
+                            testing::HasSubstr("isn't compatible"));
 }
 
 // Test that using a bind group layout with kInternalResolveAttachmentSampleType is incompatible
@@ -163,7 +163,7 @@
     pipelineDescriptor.layout = CreatePipelineLayout(/*withSampler=*/false);
 
     ASSERT_DEVICE_ERROR_MSG(device.CreateRenderPipeline(&pipelineDescriptor),
-                            testing::HasSubstr("not compatible"));
+                            testing::HasSubstr("isn't compatible"));
 }
 
 DAWN_INSTANTIATE_TEST(InternalResolveAttachmentSampleTypeTests, NullBackend());