Cleans up remaining un-needed proxy functions on frontend BGL.

- Audits and updates header includes to only include the frontend
  version when necessary.
- Makes the frontend BGL final to make it clear that it shouldn't be
  extended.

Bug: dawn:1933
Change-Id: I0cc73a799b90f5648e8bf2ee8b187951507f0678
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/145620
Reviewed-by: Brandon Jones <bajones@chromium.org>
Commit-Queue: Loko Kung <lokokung@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Austin Eng <enga@chromium.org>
diff --git a/src/dawn/native/BindGroup.cpp b/src/dawn/native/BindGroup.cpp
index 22c83a6..8ceee38 100644
--- a/src/dawn/native/BindGroup.cpp
+++ b/src/dawn/native/BindGroup.cpp
@@ -261,7 +261,7 @@
 }
 
 template <typename F>
-void ForEachUnverifiedBufferBindingIndexImpl(const BindGroupLayoutBase* bgl, F&& f) {
+void ForEachUnverifiedBufferBindingIndexImpl(const BindGroupLayoutInternalBase* bgl, F&& f) {
     uint32_t packedIndex = 0;
     for (BindingIndex bindingIndex{0}; bindingIndex < bgl->GetBufferCount(); ++bindingIndex) {
         if (bgl->GetBindingInfo(bindingIndex).buffer.minBindingSize == 0) {
@@ -279,14 +279,15 @@
 
     DAWN_TRY(device->ValidateObject(descriptor->layout));
 
+    BindGroupLayoutInternalBase* layout = descriptor->layout->GetInternalBindGroupLayout();
     DAWN_INVALID_IF(
-        descriptor->entryCount != descriptor->layout->GetUnexpandedBindingCount(),
+        descriptor->entryCount != layout->GetUnexpandedBindingCount(),
         "Number of entries (%u) did not match the number of entries (%u) specified in %s."
         "\nExpected layout: %s",
-        descriptor->entryCount, static_cast<uint32_t>(descriptor->layout->GetBindingCount()),
-        descriptor->layout, descriptor->layout->EntriesToString());
+        descriptor->entryCount, static_cast<uint32_t>(layout->GetBindingCount()), layout,
+        layout->EntriesToString());
 
-    const BindGroupLayoutInternalBase::BindingMap& bindingMap = descriptor->layout->GetBindingMap();
+    const BindGroupLayoutInternalBase::BindingMap& bindingMap = layout->GetBindingMap();
     ASSERT(bindingMap.size() <= kMaxBindingsPerPipelineLayout);
 
     ityp::bitset<BindingIndex, kMaxBindingsPerPipelineLayout> bindingsSet;
@@ -297,10 +298,10 @@
         DAWN_INVALID_IF(it == bindingMap.end(),
                         "In entries[%u], binding index %u not present in the bind group layout."
                         "\nExpected layout: %s",
-                        i, entry.binding, descriptor->layout->EntriesToString());
+                        i, entry.binding, layout->EntriesToString());
 
         BindingIndex bindingIndex = it->second;
-        ASSERT(bindingIndex < descriptor->layout->GetBindingCount());
+        ASSERT(bindingIndex < layout->GetBindingCount());
 
         DAWN_INVALID_IF(bindingsSet[bindingIndex],
                         "In entries[%u], binding index %u already used by a previous entry", i,
@@ -318,19 +319,19 @@
         const ExternalTextureBindingEntry* externalTextureBindingEntry = nullptr;
         FindInChain(entry.nextInChain, &externalTextureBindingEntry);
         if (externalTextureBindingEntry != nullptr) {
-            DAWN_TRY(ValidateExternalTextureBinding(
-                device, entry, externalTextureBindingEntry,
-                descriptor->layout->GetExternalTextureBindingExpansionMap()));
+            DAWN_TRY(
+                ValidateExternalTextureBinding(device, entry, externalTextureBindingEntry,
+                                               layout->GetExternalTextureBindingExpansionMap()));
             continue;
         } else {
-            DAWN_INVALID_IF(descriptor->layout->GetExternalTextureBindingExpansionMap().count(
-                                BindingNumber(entry.binding)),
-                            "entries[%u] is not an ExternalTexture when the layout contains an "
-                            "ExternalTexture entry.",
-                            i);
+            DAWN_INVALID_IF(
+                layout->GetExternalTextureBindingExpansionMap().count(BindingNumber(entry.binding)),
+                "entries[%u] is not an ExternalTexture when the layout contains an "
+                "ExternalTexture entry.",
+                i);
         }
 
-        const BindingInfo& bindingInfo = descriptor->layout->GetBindingInfo(bindingIndex);
+        const BindingInfo& bindingInfo = layout->GetBindingInfo(bindingIndex);
 
         // Perform binding-type specific validation.
         switch (bindingInfo.bindingType) {
@@ -365,7 +366,7 @@
     //  - Each binding must be set at most once
     //
     // We don't validate the equality because it wouldn't be possible to cover it with a test.
-    ASSERT(bindingsSet.count() == descriptor->layout->GetUnexpandedBindingCount());
+    ASSERT(bindingsSet.count() == layout->GetUnexpandedBindingCount());
 
     return {};
 }
@@ -377,8 +378,10 @@
                              void* bindingDataStart)
     : ApiObjectBase(device, descriptor->label),
       mLayout(descriptor->layout),
-      mBindingData(mLayout->ComputeBindingDataPointers(bindingDataStart)) {
-    for (BindingIndex i{0}; i < mLayout->GetBindingCount(); ++i) {
+      mBindingData(GetLayout()->ComputeBindingDataPointers(bindingDataStart)) {
+    BindGroupLayoutInternalBase* layout = GetLayout();
+
+    for (BindingIndex i{0}; i < layout->GetBindingCount(); ++i) {
         // TODO(enga): Shouldn't be needed when bindings are tightly packed.
         // This is to fill Ref<ObjectBase> holes with nullptrs.
         new (&mBindingData.bindings[i]) Ref<ObjectBase>();
@@ -387,9 +390,8 @@
     for (uint32_t i = 0; i < descriptor->entryCount; ++i) {
         const BindGroupEntry& entry = descriptor->entries[i];
 
-        BindingIndex bindingIndex =
-            descriptor->layout->GetBindingIndex(BindingNumber(entry.binding));
-        ASSERT(bindingIndex < mLayout->GetBindingCount());
+        BindingIndex bindingIndex = layout->GetBindingIndex(BindingNumber(entry.binding));
+        ASSERT(bindingIndex < layout->GetBindingCount());
 
         // Only a single binding type should be set, so once we found it we can skip to the
         // next loop iteration.
@@ -427,18 +429,15 @@
             mBoundExternalTextures.push_back(externalTextureBindingEntry->externalTexture);
 
             ExternalTextureBindingExpansionMap expansions =
-                mLayout->GetExternalTextureBindingExpansionMap();
+                layout->GetExternalTextureBindingExpansionMap();
             ExternalTextureBindingExpansionMap::iterator it =
                 expansions.find(BindingNumber(entry.binding));
 
             ASSERT(it != expansions.end());
 
-            BindingIndex plane0BindingIndex =
-                descriptor->layout->GetBindingIndex(it->second.plane0);
-            BindingIndex plane1BindingIndex =
-                descriptor->layout->GetBindingIndex(it->second.plane1);
-            BindingIndex paramsBindingIndex =
-                descriptor->layout->GetBindingIndex(it->second.params);
+            BindingIndex plane0BindingIndex = layout->GetBindingIndex(it->second.plane0);
+            BindingIndex plane1BindingIndex = layout->GetBindingIndex(it->second.plane1);
+            BindingIndex paramsBindingIndex = layout->GetBindingIndex(it->second.params);
 
             ASSERT(mBindingData.bindings[plane0BindingIndex] == nullptr);
 
@@ -460,7 +459,7 @@
         }
     }
 
-    ForEachUnverifiedBufferBindingIndexImpl(mLayout.Get(),
+    ForEachUnverifiedBufferBindingIndexImpl(layout,
                                             [&](BindingIndex bindingIndex, uint32_t packedIndex) {
                                                 mBindingData.unverifiedBufferSizes[packedIndex] =
                                                     mBindingData.bufferData[bindingIndex].size;
@@ -474,7 +473,7 @@
 void BindGroupBase::DestroyImpl() {
     if (mLayout != nullptr) {
         ASSERT(!IsError());
-        for (BindingIndex i{0}; i < mLayout->GetBindingCount(); ++i) {
+        for (BindingIndex i{0}; i < GetLayout()->GetBindingCount(); ++i) {
             mBindingData.bindings[i].~Ref<ObjectBase>();
         }
     }
@@ -500,16 +499,26 @@
     return ObjectType::BindGroup;
 }
 
-BindGroupLayoutBase* BindGroupBase::GetLayout() {
+BindGroupLayoutBase* BindGroupBase::GetFrontendLayout() {
     ASSERT(!IsError());
     return mLayout.Get();
 }
 
-const BindGroupLayoutBase* BindGroupBase::GetLayout() const {
+const BindGroupLayoutBase* BindGroupBase::GetFrontendLayout() const {
     ASSERT(!IsError());
     return mLayout.Get();
 }
 
+BindGroupLayoutInternalBase* BindGroupBase::GetLayout() {
+    ASSERT(!IsError());
+    return mLayout->GetInternalBindGroupLayout();
+}
+
+const BindGroupLayoutInternalBase* BindGroupBase::GetLayout() const {
+    ASSERT(!IsError());
+    return mLayout->GetInternalBindGroupLayout();
+}
+
 const ityp::span<uint32_t, uint64_t>& BindGroupBase::GetUnverifiedBufferSizes() const {
     ASSERT(!IsError());
     return mBindingData.unverifiedBufferSizes;
@@ -517,8 +526,9 @@
 
 BufferBinding BindGroupBase::GetBindingAsBufferBinding(BindingIndex bindingIndex) {
     ASSERT(!IsError());
-    ASSERT(bindingIndex < mLayout->GetBindingCount());
-    ASSERT(mLayout->GetBindingInfo(bindingIndex).bindingType == BindingInfoType::Buffer);
+    const BindGroupLayoutInternalBase* layout = GetLayout();
+    ASSERT(bindingIndex < layout->GetBindingCount());
+    ASSERT(layout->GetBindingInfo(bindingIndex).bindingType == BindingInfoType::Buffer);
     BufferBase* buffer = static_cast<BufferBase*>(mBindingData.bindings[bindingIndex].Get());
     return {buffer, mBindingData.bufferData[bindingIndex].offset,
             mBindingData.bufferData[bindingIndex].size};
@@ -526,16 +536,18 @@
 
 SamplerBase* BindGroupBase::GetBindingAsSampler(BindingIndex bindingIndex) const {
     ASSERT(!IsError());
-    ASSERT(bindingIndex < mLayout->GetBindingCount());
-    ASSERT(mLayout->GetBindingInfo(bindingIndex).bindingType == BindingInfoType::Sampler);
+    const BindGroupLayoutInternalBase* layout = GetLayout();
+    ASSERT(bindingIndex < layout->GetBindingCount());
+    ASSERT(layout->GetBindingInfo(bindingIndex).bindingType == BindingInfoType::Sampler);
     return static_cast<SamplerBase*>(mBindingData.bindings[bindingIndex].Get());
 }
 
 TextureViewBase* BindGroupBase::GetBindingAsTextureView(BindingIndex bindingIndex) {
     ASSERT(!IsError());
-    ASSERT(bindingIndex < mLayout->GetBindingCount());
-    ASSERT(mLayout->GetBindingInfo(bindingIndex).bindingType == BindingInfoType::Texture ||
-           mLayout->GetBindingInfo(bindingIndex).bindingType == BindingInfoType::StorageTexture);
+    const BindGroupLayoutInternalBase* layout = GetLayout();
+    ASSERT(bindingIndex < layout->GetBindingCount());
+    ASSERT(layout->GetBindingInfo(bindingIndex).bindingType == BindingInfoType::Texture ||
+           layout->GetBindingInfo(bindingIndex).bindingType == BindingInfoType::StorageTexture);
     return static_cast<TextureViewBase*>(mBindingData.bindings[bindingIndex].Get());
 }
 
@@ -545,7 +557,7 @@
 
 void BindGroupBase::ForEachUnverifiedBufferBindingIndex(
     std::function<void(BindingIndex, uint32_t)> fn) const {
-    ForEachUnverifiedBufferBindingIndexImpl(mLayout.Get(), fn);
+    ForEachUnverifiedBufferBindingIndexImpl(GetLayout(), fn);
 }
 
 }  // namespace dawn::native
diff --git a/src/dawn/native/BindGroup.h b/src/dawn/native/BindGroup.h
index acf4363..1e8c550 100644
--- a/src/dawn/native/BindGroup.h
+++ b/src/dawn/native/BindGroup.h
@@ -48,8 +48,11 @@
 
     ObjectType GetType() const override;
 
-    BindGroupLayoutBase* GetLayout();
-    const BindGroupLayoutBase* GetLayout() const;
+    BindGroupLayoutBase* GetFrontendLayout();
+    const BindGroupLayoutBase* GetFrontendLayout() const;
+    BindGroupLayoutInternalBase* GetLayout();
+    const BindGroupLayoutInternalBase* GetLayout() const;
+
     BufferBinding GetBindingAsBufferBinding(BindingIndex bindingIndex);
     SamplerBase* GetBindingAsSampler(BindingIndex bindingIndex) const;
     TextureViewBase* GetBindingAsTextureView(BindingIndex bindingIndex);
@@ -71,10 +74,12 @@
     // be first in the allocation. The binding data is stored after the Derived class.
     template <typename Derived>
     BindGroupBase(Derived* derived, DeviceBase* device, const BindGroupDescriptor* descriptor)
-        : BindGroupBase(device,
-                        descriptor,
-                        AlignPtr(reinterpret_cast<char*>(derived) + sizeof(Derived),
-                                 descriptor->layout->GetBindingDataAlignment())) {
+        : BindGroupBase(
+              device,
+              descriptor,
+              AlignPtr(
+                  reinterpret_cast<char*>(derived) + sizeof(Derived),
+                  descriptor->layout->GetInternalBindGroupLayout()->GetBindingDataAlignment())) {
         static_assert(std::is_base_of<BindGroupBase, Derived>::value);
     }
 
diff --git a/src/dawn/native/BindGroupLayout.h b/src/dawn/native/BindGroupLayout.h
index b0513c2..309cba1 100644
--- a/src/dawn/native/BindGroupLayout.h
+++ b/src/dawn/native/BindGroupLayout.h
@@ -25,8 +25,7 @@
 
 // Wrapper passthrough frontend object that is essentially just a Ref to a backing
 // BindGroupLayoutInternalBase and a pipeline compatibility token.
-// TODO(lokokung) Could maybe make this a final class if we update the mock objects.
-class BindGroupLayoutBase : public ApiObjectBase {
+class BindGroupLayoutBase final : public ApiObjectBase {
   public:
     BindGroupLayoutBase(DeviceBase* device,
                         const char* label,
@@ -37,50 +36,6 @@
 
     ObjectType GetType() const override;
 
-    // Proxy functions that just call their respective counterparts in the internal layout.
-    const BindingInfo& GetBindingInfo(BindingIndex bindingIndex) const {
-        return mInternalLayout->GetBindingInfo(bindingIndex);
-    }
-    const BindGroupLayoutInternalBase::BindingMap& GetBindingMap() const {
-        return mInternalLayout->GetBindingMap();
-    }
-    bool HasBinding(BindingNumber bindingNumber) const {
-        return mInternalLayout->HasBinding(bindingNumber);
-    }
-    BindingIndex GetBindingIndex(BindingNumber bindingNumber) const {
-        return mInternalLayout->GetBindingIndex(bindingNumber);
-    }
-    BindingIndex GetBindingCount() const { return mInternalLayout->GetBindingCount(); }
-    BindingIndex GetBufferCount() const { return mInternalLayout->GetBufferCount(); }
-    BindingIndex GetDynamicBufferCount() const { return mInternalLayout->GetDynamicBufferCount(); }
-    uint32_t GetUnverifiedBufferCount() const {
-        return mInternalLayout->GetUnverifiedBufferCount();
-    }
-    const BindingCounts& GetBindingCountInfo() const {
-        return mInternalLayout->GetBindingCountInfo();
-    }
-    uint32_t GetExternalTextureBindingCount() const {
-        return mInternalLayout->GetExternalTextureBindingCount();
-    }
-    const ExternalTextureBindingExpansionMap& GetExternalTextureBindingExpansionMap() const {
-        return mInternalLayout->GetExternalTextureBindingExpansionMap();
-    }
-    uint32_t GetUnexpandedBindingCount() const {
-        return mInternalLayout->GetUnexpandedBindingCount();
-    }
-    size_t GetBindingDataSize() const { return mInternalLayout->GetBindingDataSize(); }
-    static constexpr size_t GetBindingDataAlignment() {
-        return BindGroupLayoutInternalBase::GetBindingDataAlignment();
-    }
-    BindGroupLayoutInternalBase::BindingDataPointers ComputeBindingDataPointers(
-        void* dataStart) const {
-        return mInternalLayout->ComputeBindingDataPointers(dataStart);
-    }
-    bool IsStorageBufferBinding(BindingIndex bindingIndex) const {
-        return mInternalLayout->IsStorageBufferBinding(bindingIndex);
-    }
-    std::string EntriesToString() const { return mInternalLayout->EntriesToString(); }
-
     // Non-proxy functions that are specific to the realized frontend object.
     BindGroupLayoutInternalBase* GetInternalBindGroupLayout() const;
     bool IsLayoutEqual(const BindGroupLayoutBase* other,
diff --git a/src/dawn/native/BindGroupTracker.h b/src/dawn/native/BindGroupTracker.h
index feccd59..21e6216 100644
--- a/src/dawn/native/BindGroupTracker.h
+++ b/src/dawn/native/BindGroupTracker.h
@@ -20,7 +20,7 @@
 #include <bitset>
 
 #include "dawn/common/Constants.h"
-#include "dawn/native/BindGroupLayout.h"
+#include "dawn/native/BindGroup.h"
 #include "dawn/native/Pipeline.h"
 #include "dawn/native/PipelineLayout.h"
 
diff --git a/src/dawn/native/CommandBufferStateTracker.cpp b/src/dawn/native/CommandBufferStateTracker.cpp
index 6eb25bd..5503849 100644
--- a/src/dawn/native/CommandBufferStateTracker.cpp
+++ b/src/dawn/native/CommandBufferStateTracker.cpp
@@ -107,7 +107,7 @@
     StackVector<std::pair<BindGroupIndex, BindingIndex>, 8> textureBindingIndices;
 
     for (BindGroupIndex groupIndex : IterateBitSet(pipelineLayout->GetBindGroupLayoutsMask())) {
-        BindGroupLayoutBase* bgl = bindGroups[groupIndex]->GetLayout();
+        BindGroupLayoutInternalBase* bgl = bindGroups[groupIndex]->GetLayout();
 
         for (BindingIndex bindingIndex{0}; bindingIndex < bgl->GetBufferCount(); ++bindingIndex) {
             const BindingInfo& bindingInfo = bgl->GetBindingInfo(bindingIndex);
@@ -340,7 +340,7 @@
     for (BindGroupIndex groupIndex :
          IterateBitSet(mLastPipelineLayout->GetBindGroupLayoutsMask())) {
         BindGroupBase* bindGroup = mBindgroups[groupIndex];
-        BindGroupLayoutBase* bgl = bindGroup->GetLayout();
+        BindGroupLayoutInternalBase* bgl = bindGroup->GetLayout();
 
         for (BindingIndex bindingIndex{0}; bindingIndex < bgl->GetBindingCount(); ++bindingIndex) {
             const BindingInfo& bindingInfo = bgl->GetBindingInfo(bindingIndex);
@@ -510,8 +510,7 @@
 
         for (BindGroupIndex i : IterateBitSet(mLastPipelineLayout->GetBindGroupLayoutsMask())) {
             if (mBindgroups[i] == nullptr ||
-                mLastPipelineLayout->GetBindGroupLayout(i)->GetInternalBindGroupLayout() !=
-                    mBindgroups[i]->GetLayout()->GetInternalBindGroupLayout() ||
+                mLastPipelineLayout->GetBindGroupLayout(i) != mBindgroups[i]->GetLayout() ||
                 FindFirstUndersizedBuffer(mBindgroups[i]->GetUnverifiedBufferSizes(),
                                           (*mMinBufferSizes)[i])
                     .has_value()) {
@@ -606,8 +605,8 @@
             DAWN_INVALID_IF(mBindgroups[i] == nullptr, "No bind group set at group index %u.",
                             static_cast<uint32_t>(i));
 
-            BindGroupLayoutBase* requiredBGL = mLastPipelineLayout->GetBindGroupLayout(i);
-            BindGroupLayoutBase* currentBGL = mBindgroups[i]->GetLayout();
+            BindGroupLayoutBase* requiredBGL = mLastPipelineLayout->GetFrontendBindGroupLayout(i);
+            BindGroupLayoutBase* currentBGL = mBindgroups[i]->GetFrontendLayout();
 
             DAWN_INVALID_IF(
                 requiredBGL->GetPipelineCompatibilityToken() != PipelineCompatibilityToken(0) &&
@@ -633,8 +632,8 @@
                 mBindgroups[i], static_cast<uint32_t>(i), currentBGL, mLastPipeline);
 
             DAWN_INVALID_IF(
-                mLastPipelineLayout->GetBindGroupLayout(i)->GetInternalBindGroupLayout() !=
-                    mBindgroups[i]->GetLayout()->GetInternalBindGroupLayout(),
+                requiredBGL->GetInternalBindGroupLayout() !=
+                    currentBGL->GetInternalBindGroupLayout(),
                 "Bind group layout %s of pipeline layout %s does not match layout %s of bind "
                 "group %s set at group index %u.",
                 requiredBGL, mLastPipelineLayout, currentBGL, mBindgroups[i],
diff --git a/src/dawn/native/Pipeline.cpp b/src/dawn/native/Pipeline.cpp
index 7a217a5..9f6f447 100644
--- a/src/dawn/native/Pipeline.cpp
+++ b/src/dawn/native/Pipeline.cpp
@@ -271,7 +271,7 @@
     BindGroupIndex groupIndex(groupIndexIn);
 
     DAWN_TRY(ValidateGetBindGroupLayout(groupIndex));
-    return Ref<BindGroupLayoutBase>(mLayout->GetBindGroupLayout(groupIndex));
+    return Ref<BindGroupLayoutBase>(mLayout->GetFrontendBindGroupLayout(groupIndex));
 }
 
 BindGroupLayoutBase* PipelineBase::APIGetBindGroupLayout(uint32_t groupIndexIn) {
diff --git a/src/dawn/native/PipelineLayout.cpp b/src/dawn/native/PipelineLayout.cpp
index fac4693..365c092 100644
--- a/src/dawn/native/PipelineLayout.cpp
+++ b/src/dawn/native/PipelineLayout.cpp
@@ -47,8 +47,9 @@
                         "created as part of a pipeline's default layout.",
                         i, descriptor->bindGroupLayouts[i]);
 
-        AccumulateBindingCounts(&bindingCounts,
-                                descriptor->bindGroupLayouts[i]->GetBindingCountInfo());
+        AccumulateBindingCounts(
+            &bindingCounts,
+            descriptor->bindGroupLayouts[i]->GetInternalBindGroupLayout()->GetBindingCountInfo());
     }
 
     DAWN_TRY(ValidateBindingCounts(device->GetLimits(), bindingCounts));
@@ -335,7 +336,8 @@
     return ObjectType::PipelineLayout;
 }
 
-const BindGroupLayoutBase* PipelineLayoutBase::GetBindGroupLayout(BindGroupIndex group) const {
+const BindGroupLayoutBase* PipelineLayoutBase::GetFrontendBindGroupLayout(
+    BindGroupIndex group) const {
     ASSERT(!IsError());
     ASSERT(group < kMaxBindGroupsTyped);
     ASSERT(mMask[group]);
@@ -344,7 +346,7 @@
     return bgl;
 }
 
-BindGroupLayoutBase* PipelineLayoutBase::GetBindGroupLayout(BindGroupIndex group) {
+BindGroupLayoutBase* PipelineLayoutBase::GetFrontendBindGroupLayout(BindGroupIndex group) {
     ASSERT(!IsError());
     ASSERT(group < kMaxBindGroupsTyped);
     ASSERT(mMask[group]);
@@ -353,6 +355,15 @@
     return bgl;
 }
 
+const BindGroupLayoutInternalBase* PipelineLayoutBase::GetBindGroupLayout(
+    BindGroupIndex group) const {
+    return GetFrontendBindGroupLayout(group)->GetInternalBindGroupLayout();
+}
+
+BindGroupLayoutInternalBase* PipelineLayoutBase::GetBindGroupLayout(BindGroupIndex group) {
+    return GetFrontendBindGroupLayout(group)->GetInternalBindGroupLayout();
+}
+
 const BindGroupLayoutMask& PipelineLayoutBase::GetBindGroupLayoutsMask() const {
     ASSERT(!IsError());
     return mMask;
@@ -379,7 +390,7 @@
     recorder.Record(mMask);
 
     for (BindGroupIndex group : IterateBitSet(mMask)) {
-        recorder.Record(GetBindGroupLayout(group)->GetInternalBindGroupLayout()->GetContentHash());
+        recorder.Record(GetBindGroupLayout(group)->GetContentHash());
     }
 
     return recorder.GetContentHash();
diff --git a/src/dawn/native/PipelineLayout.h b/src/dawn/native/PipelineLayout.h
index 6f89786..8a0c86f 100644
--- a/src/dawn/native/PipelineLayout.h
+++ b/src/dawn/native/PipelineLayout.h
@@ -67,8 +67,10 @@
 
     ObjectType GetType() const override;
 
-    const BindGroupLayoutBase* GetBindGroupLayout(BindGroupIndex group) const;
-    BindGroupLayoutBase* GetBindGroupLayout(BindGroupIndex group);
+    const BindGroupLayoutBase* GetFrontendBindGroupLayout(BindGroupIndex group) const;
+    BindGroupLayoutBase* GetFrontendBindGroupLayout(BindGroupIndex group);
+    const BindGroupLayoutInternalBase* GetBindGroupLayout(BindGroupIndex group) const;
+    BindGroupLayoutInternalBase* GetBindGroupLayout(BindGroupIndex group);
     const BindGroupLayoutMask& GetBindGroupLayoutsMask() const;
 
     // Utility functions to compute inherited bind groups.
diff --git a/src/dawn/native/ProgrammableEncoder.cpp b/src/dawn/native/ProgrammableEncoder.cpp
index f414ce1..ead9225 100644
--- a/src/dawn/native/ProgrammableEncoder.cpp
+++ b/src/dawn/native/ProgrammableEncoder.cpp
@@ -125,7 +125,7 @@
     DAWN_TRY(GetDevice()->ValidateObject(group));
 
     // Dynamic offsets count must match the number required by the layout perfectly.
-    const BindGroupLayoutBase* layout = group->GetLayout();
+    const BindGroupLayoutInternalBase* layout = group->GetLayout();
     DAWN_INVALID_IF(
         layout->GetDynamicBufferCount() != dynamicOffsets.size(),
         "The number of dynamic offsets (%u) does not match the number of dynamic buffers (%u) "
diff --git a/src/dawn/native/ShaderModule.cpp b/src/dawn/native/ShaderModule.cpp
index aba2380..650dc82 100644
--- a/src/dawn/native/ShaderModule.cpp
+++ b/src/dawn/native/ShaderModule.cpp
@@ -20,7 +20,7 @@
 #include "absl/strings/str_format.h"
 #include "dawn/common/BitSetIterator.h"
 #include "dawn/common/Constants.h"
-#include "dawn/native/BindGroupLayout.h"
+#include "dawn/native/BindGroupLayoutInternal.h"
 #include "dawn/native/ChainUtils.h"
 #include "dawn/native/CompilationMessages.h"
 #include "dawn/native/Device.h"
@@ -337,7 +337,7 @@
 #endif  // TINT_BUILD_SPV_READER
 
 std::vector<uint64_t> GetBindGroupMinBufferSizes(const BindingGroupInfoMap& shaderBindings,
-                                                 const BindGroupLayoutBase* layout) {
+                                                 const BindGroupLayoutInternalBase* layout) {
     std::vector<uint64_t> requiredBufferSizes(layout->GetUnverifiedBufferCount());
     uint32_t packedIdx = 0;
 
@@ -365,7 +365,7 @@
 }
 
 MaybeError ValidateCompatibilityOfSingleBindingWithLayout(const DeviceBase* device,
-                                                          const BindGroupLayoutBase* layout,
+                                                          const BindGroupLayoutInternalBase* layout,
                                                           SingleShaderStage entryPointStage,
                                                           BindingNumber bindingNumber,
                                                           const ShaderBindingInfo& shaderInfo) {
@@ -507,7 +507,7 @@
 MaybeError ValidateCompatibilityWithBindGroupLayout(DeviceBase* device,
                                                     BindGroupIndex group,
                                                     const EntryPointMetadata& entryPoint,
-                                                    const BindGroupLayoutBase* layout) {
+                                                    const BindGroupLayoutInternalBase* layout) {
     // Iterate over all bindings used by this group in the shader, and find the
     // corresponding binding in the BindGroupLayout, if it exists.
     for (const auto& [bindingId, bindingInfo] : entryPoint.bindings[group]) {
@@ -1051,13 +1051,15 @@
 
     // Validate that filtering samplers are not used with unfilterable textures.
     for (const auto& pair : entryPoint.samplerTexturePairs) {
-        const BindGroupLayoutBase* samplerBGL = layout->GetBindGroupLayout(pair.sampler.group);
+        const BindGroupLayoutInternalBase* samplerBGL =
+            layout->GetBindGroupLayout(pair.sampler.group);
         const BindingInfo& samplerInfo =
             samplerBGL->GetBindingInfo(samplerBGL->GetBindingIndex(pair.sampler.binding));
         if (samplerInfo.sampler.type != wgpu::SamplerBindingType::Filtering) {
             continue;
         }
-        const BindGroupLayoutBase* textureBGL = layout->GetBindGroupLayout(pair.texture.group);
+        const BindGroupLayoutInternalBase* textureBGL =
+            layout->GetBindGroupLayout(pair.texture.group);
         const BindingInfo& textureInfo =
             textureBGL->GetBindingInfo(textureBGL->GetBindingIndex(pair.texture.binding));
 
diff --git a/src/dawn/native/TintUtils.cpp b/src/dawn/native/TintUtils.cpp
index 1d2dfd4..19974b5 100644
--- a/src/dawn/native/TintUtils.cpp
+++ b/src/dawn/native/TintUtils.cpp
@@ -14,7 +14,7 @@
 
 #include "dawn/native/TintUtils.h"
 
-#include "dawn/native/BindGroupLayout.h"
+#include "dawn/native/BindGroupLayoutInternal.h"
 #include "dawn/native/Device.h"
 #include "dawn/native/Pipeline.h"
 #include "dawn/native/PipelineLayout.h"
@@ -145,7 +145,7 @@
     const PipelineLayoutBase* layout) {
     tint::ExternalTextureOptions options;
     for (BindGroupIndex i : IterateBitSet(layout->GetBindGroupLayoutsMask())) {
-        const BindGroupLayoutBase* bgl = layout->GetBindGroupLayout(i);
+        const BindGroupLayoutInternalBase* bgl = layout->GetBindGroupLayout(i);
         for (const auto& [_, expansion] : bgl->GetExternalTextureBindingExpansionMap()) {
             options.bindings_map[{static_cast<uint32_t>(i),
                                   static_cast<uint32_t>(expansion.plane0)}] = {
diff --git a/src/dawn/native/d3d11/BindGroupD3D11.cpp b/src/dawn/native/d3d11/BindGroupD3D11.cpp
index e2e3f85..834f930 100644
--- a/src/dawn/native/d3d11/BindGroupD3D11.cpp
+++ b/src/dawn/native/d3d11/BindGroupD3D11.cpp
@@ -35,7 +35,7 @@
 
 void BindGroup::DestroyImpl() {
     BindGroupBase::DestroyImpl();
-    ToBackend(GetLayout()->GetInternalBindGroupLayout())->DeallocateBindGroup(this);
+    ToBackend(GetLayout())->DeallocateBindGroup(this);
 }
 
 }  // namespace dawn::native::d3d11
diff --git a/src/dawn/native/d3d11/BindGroupTrackerD3D11.cpp b/src/dawn/native/d3d11/BindGroupTrackerD3D11.cpp
index 7181789..238bf56 100644
--- a/src/dawn/native/d3d11/BindGroupTrackerD3D11.cpp
+++ b/src/dawn/native/d3d11/BindGroupTrackerD3D11.cpp
@@ -392,7 +392,8 @@
 
 void BindGroupTracker::UnApplyBindGroup(BindGroupIndex index) {
     ID3D11DeviceContext1* deviceContext1 = mCommandContext->GetD3D11DeviceContext1();
-    BindGroupLayoutBase* groupLayout = mLastAppliedPipelineLayout->GetBindGroupLayout(index);
+    BindGroupLayoutInternalBase* groupLayout =
+        mLastAppliedPipelineLayout->GetBindGroupLayout(index);
     const auto& indices = ToBackend(mLastAppliedPipelineLayout)->GetBindingIndexInfo()[index];
 
     for (BindingIndex bindingIndex{0}; bindingIndex < groupLayout->GetBindingCount();
diff --git a/src/dawn/native/d3d11/PipelineLayoutD3D11.cpp b/src/dawn/native/d3d11/PipelineLayoutD3D11.cpp
index 833c54e..c00e423 100644
--- a/src/dawn/native/d3d11/PipelineLayoutD3D11.cpp
+++ b/src/dawn/native/d3d11/PipelineLayoutD3D11.cpp
@@ -15,7 +15,7 @@
 #include "dawn/native/d3d11/PipelineLayoutD3D11.h"
 
 #include "dawn/common/BitSetIterator.h"
-#include "dawn/native/BindGroupLayout.h"
+#include "dawn/native/BindGroupLayoutInternal.h"
 #include "dawn/native/d3d11/DeviceD3D11.h"
 
 namespace dawn::native::d3d11 {
@@ -41,7 +41,7 @@
     mTotalUAVBindingCount = unorderedAccessViewIndex;
 
     for (BindGroupIndex group : IterateBitSet(GetBindGroupLayoutsMask())) {
-        const BindGroupLayoutBase* bgl = GetBindGroupLayout(group);
+        const BindGroupLayoutInternalBase* bgl = GetBindGroupLayout(group);
         mIndexInfo[group].resize(bgl->GetBindingCount());
 
         for (BindingIndex bindingIndex{0}; bindingIndex < bgl->GetBindingCount(); ++bindingIndex) {
diff --git a/src/dawn/native/d3d11/ShaderModuleD3D11.cpp b/src/dawn/native/d3d11/ShaderModuleD3D11.cpp
index d1907c0..8f90985 100644
--- a/src/dawn/native/d3d11/ShaderModuleD3D11.cpp
+++ b/src/dawn/native/d3d11/ShaderModuleD3D11.cpp
@@ -113,8 +113,7 @@
     const BindingInfoArray& moduleBindingInfo = entryPoint.bindings;
 
     for (BindGroupIndex group : IterateBitSet(layout->GetBindGroupLayoutsMask())) {
-        const BindGroupLayout* groupLayout =
-            ToBackend(layout->GetBindGroupLayout(group)->GetInternalBindGroupLayout());
+        const BindGroupLayout* groupLayout = ToBackend(layout->GetBindGroupLayout(group));
         const auto& indices = layout->GetBindingIndexInfo()[group];
         const auto& groupBindingInfo = moduleBindingInfo[group];
 
diff --git a/src/dawn/native/d3d12/BindGroupD3D12.cpp b/src/dawn/native/d3d12/BindGroupD3D12.cpp
index 56160cf..8100cc8 100644
--- a/src/dawn/native/d3d12/BindGroupD3D12.cpp
+++ b/src/dawn/native/d3d12/BindGroupD3D12.cpp
@@ -39,7 +39,7 @@
                      uint32_t viewSizeIncrement,
                      const CPUDescriptorHeapAllocation& viewAllocation)
     : BindGroupBase(this, device, descriptor) {
-    BindGroupLayout* bgl = ToBackend(GetLayout()->GetInternalBindGroupLayout());
+    BindGroupLayout* bgl = ToBackend(GetLayout());
 
     mCPUViewAllocation = viewAllocation;
 
@@ -208,13 +208,12 @@
 
 void BindGroup::DestroyImpl() {
     BindGroupBase::DestroyImpl();
-    ToBackend(GetLayout()->GetInternalBindGroupLayout())
-        ->DeallocateBindGroup(this, &mCPUViewAllocation);
+    ToBackend(GetLayout())->DeallocateBindGroup(this, &mCPUViewAllocation);
     ASSERT(!mCPUViewAllocation.IsValid());
 }
 
 bool BindGroup::PopulateViews(ShaderVisibleDescriptorAllocator* viewAllocator) {
-    const BindGroupLayout* bgl = ToBackend(GetLayout()->GetInternalBindGroupLayout());
+    const BindGroupLayout* bgl = ToBackend(GetLayout());
 
     const uint32_t descriptorCount = bgl->GetCbvUavSrvDescriptorCount();
     if (descriptorCount == 0 || viewAllocator->IsAllocationStillValid(mGPUViewAllocation)) {
diff --git a/src/dawn/native/d3d12/CommandBufferD3D12.cpp b/src/dawn/native/d3d12/CommandBufferD3D12.cpp
index 8421e9e..6c57af3 100644
--- a/src/dawn/native/d3d12/CommandBufferD3D12.cpp
+++ b/src/dawn/native/d3d12/CommandBufferD3D12.cpp
@@ -548,10 +548,9 @@
             return;
         }
 
-        const uint32_t cbvUavSrvCount = ToBackend(group->GetLayout()->GetInternalBindGroupLayout())
-                                            ->GetCbvUavSrvDescriptorCount();
-        const uint32_t samplerCount = ToBackend(group->GetLayout()->GetInternalBindGroupLayout())
-                                          ->GetSamplerDescriptorCount();
+        const uint32_t cbvUavSrvCount =
+            ToBackend(group->GetLayout())->GetCbvUavSrvDescriptorCount();
+        const uint32_t samplerCount = ToBackend(group->GetLayout())->GetSamplerDescriptorCount();
 
         if (cbvUavSrvCount > 0) {
             uint32_t parameterIndex = pipelineLayout->GetCbvUavSrvRootParameterIndex(index);
diff --git a/src/dawn/native/d3d12/PipelineLayoutD3D12.cpp b/src/dawn/native/d3d12/PipelineLayoutD3D12.cpp
index f6a8167..8cf0351 100644
--- a/src/dawn/native/d3d12/PipelineLayoutD3D12.cpp
+++ b/src/dawn/native/d3d12/PipelineLayoutD3D12.cpp
@@ -157,8 +157,7 @@
 
     size_t rangesCount = 0;
     for (BindGroupIndex group : IterateBitSet(GetBindGroupLayoutsMask())) {
-        const BindGroupLayout* bindGroupLayout =
-            ToBackend(GetBindGroupLayout(group)->GetInternalBindGroupLayout());
+        const BindGroupLayout* bindGroupLayout = ToBackend(GetBindGroupLayout(group));
         rangesCount += bindGroupLayout->GetCbvUavSrvDescriptorRanges().size() +
                        bindGroupLayout->GetSamplerDescriptorRanges().size();
     }
@@ -169,8 +168,7 @@
     uint32_t rangeIndex = 0;
 
     for (BindGroupIndex group : IterateBitSet(GetBindGroupLayoutsMask())) {
-        const BindGroupLayout* bindGroupLayout =
-            ToBackend(GetBindGroupLayout(group)->GetInternalBindGroupLayout());
+        const BindGroupLayout* bindGroupLayout = ToBackend(GetBindGroupLayout(group));
 
         // Set the root descriptor table parameter and copy ranges. Ranges are offset by the
         // bind group index Returns whether or not the parameter was set. A root parameter is
@@ -281,7 +279,7 @@
     // data should start.
     uint32_t dynamicStorageBufferLengthsShaderRegisterOffset = 0;
     for (BindGroupIndex group : IterateBitSet(GetBindGroupLayoutsMask())) {
-        const BindGroupLayoutBase* bgl = GetBindGroupLayout(group);
+        const BindGroupLayoutInternalBase* bgl = GetBindGroupLayout(group);
 
         mDynamicStorageBufferLengthInfo[group].firstRegisterOffset =
             dynamicStorageBufferLengthsShaderRegisterOffset;
diff --git a/src/dawn/native/d3d12/SamplerHeapCacheD3D12.cpp b/src/dawn/native/d3d12/SamplerHeapCacheD3D12.cpp
index 4bbad54..f1d12e3 100644
--- a/src/dawn/native/d3d12/SamplerHeapCacheD3D12.cpp
+++ b/src/dawn/native/d3d12/SamplerHeapCacheD3D12.cpp
@@ -91,7 +91,7 @@
 ResultOrError<Ref<SamplerHeapCacheEntry>> SamplerHeapCache::GetOrCreate(
     const BindGroup* group,
     StagingDescriptorAllocator* samplerAllocator) {
-    const BindGroupLayout* bgl = ToBackend(group->GetLayout()->GetInternalBindGroupLayout());
+    const BindGroupLayout* bgl = ToBackend(group->GetLayout());
 
     // If a previously created bindgroup used the same samplers, the backing sampler heap
     // allocation can be reused. The packed list of samplers acts as the key to lookup the
diff --git a/src/dawn/native/d3d12/ShaderModuleD3D12.cpp b/src/dawn/native/d3d12/ShaderModuleD3D12.cpp
index 4479a65..7ac788f 100644
--- a/src/dawn/native/d3d12/ShaderModuleD3D12.cpp
+++ b/src/dawn/native/d3d12/ShaderModuleD3D12.cpp
@@ -131,8 +131,7 @@
 
     const BindingInfoArray& moduleBindingInfo = entryPoint.bindings;
     for (BindGroupIndex group : IterateBitSet(layout->GetBindGroupLayoutsMask())) {
-        const BindGroupLayout* bgl =
-            ToBackend(layout->GetBindGroupLayout(group)->GetInternalBindGroupLayout());
+        const BindGroupLayout* bgl = ToBackend(layout->GetBindGroupLayout(group));
         const auto& moduleGroupBindingInfo = moduleBindingInfo[group];
 
         // d3d12::BindGroupLayout packs the bindings per HLSL register-space. We modify
diff --git a/src/dawn/native/metal/BindGroupMTL.mm b/src/dawn/native/metal/BindGroupMTL.mm
index 73a8adf..4dfcaa2 100644
--- a/src/dawn/native/metal/BindGroupMTL.mm
+++ b/src/dawn/native/metal/BindGroupMTL.mm
@@ -25,7 +25,7 @@
 
 void BindGroup::DestroyImpl() {
     BindGroupBase::DestroyImpl();
-    ToBackend(GetLayout()->GetInternalBindGroupLayout())->DeallocateBindGroup(this);
+    ToBackend(GetLayout())->DeallocateBindGroup(this);
 }
 
 // static
diff --git a/src/dawn/native/metal/DeviceMTL.mm b/src/dawn/native/metal/DeviceMTL.mm
index 494e040..de0052d 100644
--- a/src/dawn/native/metal/DeviceMTL.mm
+++ b/src/dawn/native/metal/DeviceMTL.mm
@@ -18,7 +18,6 @@
 #include "dawn/common/Platform.h"
 #include "dawn/native/Adapter.h"
 #include "dawn/native/BackendConnection.h"
-#include "dawn/native/BindGroupLayout.h"
 #include "dawn/native/Commands.h"
 #include "dawn/native/ErrorData.h"
 #include "dawn/native/metal/BindGroupLayoutMTL.h"
diff --git a/src/dawn/native/metal/PipelineLayoutMTL.mm b/src/dawn/native/metal/PipelineLayoutMTL.mm
index a14f82e..58217e7 100644
--- a/src/dawn/native/metal/PipelineLayoutMTL.mm
+++ b/src/dawn/native/metal/PipelineLayoutMTL.mm
@@ -15,7 +15,7 @@
 #include "dawn/native/metal/PipelineLayoutMTL.h"
 
 #include "dawn/common/BitSetIterator.h"
-#include "dawn/native/BindGroupLayout.h"
+#include "dawn/native/BindGroupLayoutInternal.h"
 #include "dawn/native/metal/DeviceMTL.h"
 
 namespace dawn::native::metal {
diff --git a/src/dawn/native/metal/ShaderModuleMTL.mm b/src/dawn/native/metal/ShaderModuleMTL.mm
index 7c8e577..22d79d7 100644
--- a/src/dawn/native/metal/ShaderModuleMTL.mm
+++ b/src/dawn/native/metal/ShaderModuleMTL.mm
@@ -14,7 +14,7 @@
 
 #include "dawn/native/metal/ShaderModuleMTL.h"
 
-#include "dawn/native/BindGroupLayout.h"
+#include "dawn/native/BindGroupLayoutInternal.h"
 #include "dawn/native/CacheRequest.h"
 #include "dawn/native/Serializable.h"
 #include "dawn/native/TintUtils.h"
diff --git a/src/dawn/native/null/DeviceNull.cpp b/src/dawn/native/null/DeviceNull.cpp
index 9296027..a69c0b7 100644
--- a/src/dawn/native/null/DeviceNull.cpp
+++ b/src/dawn/native/null/DeviceNull.cpp
@@ -306,7 +306,7 @@
 // BindGroup
 
 BindGroup::BindGroup(DeviceBase* device, const BindGroupDescriptor* descriptor)
-    : BindGroupDataHolder(descriptor->layout->GetBindingDataSize()),
+    : BindGroupDataHolder(descriptor->layout->GetInternalBindGroupLayout()->GetBindingDataSize()),
       BindGroupBase(device, descriptor, mBindingDataAllocation) {}
 
 // BindGroupLayout
diff --git a/src/dawn/native/opengl/BindGroupGL.cpp b/src/dawn/native/opengl/BindGroupGL.cpp
index 147138b..6d70b1e 100644
--- a/src/dawn/native/opengl/BindGroupGL.cpp
+++ b/src/dawn/native/opengl/BindGroupGL.cpp
@@ -21,15 +21,16 @@
 namespace dawn::native::opengl {
 
 MaybeError ValidateGLBindGroupDescriptor(const BindGroupDescriptor* descriptor) {
-    const BindGroupLayoutInternalBase::BindingMap& bindingMap = descriptor->layout->GetBindingMap();
+    BindGroupLayoutInternalBase* layout = descriptor->layout->GetInternalBindGroupLayout();
+    const BindGroupLayoutInternalBase::BindingMap& bindingMap = layout->GetBindingMap();
     for (uint32_t i = 0; i < descriptor->entryCount; ++i) {
         const BindGroupEntry& entry = descriptor->entries[i];
 
         const auto& it = bindingMap.find(BindingNumber(entry.binding));
         BindingIndex bindingIndex = it->second;
-        ASSERT(bindingIndex < descriptor->layout->GetBindingCount());
+        ASSERT(bindingIndex < layout->GetBindingCount());
 
-        const BindingInfo& bindingInfo = descriptor->layout->GetBindingInfo(bindingIndex);
+        const BindingInfo& bindingInfo = layout->GetBindingInfo(bindingIndex);
         if (bindingInfo.bindingType == BindingInfoType::StorageTexture) {
             ASSERT(entry.textureView != nullptr);
             const uint32_t textureViewLayerCount = entry.textureView->GetLayerCount();
@@ -53,7 +54,7 @@
 
 void BindGroup::DestroyImpl() {
     BindGroupBase::DestroyImpl();
-    ToBackend(GetLayout()->GetInternalBindGroupLayout())->DeallocateBindGroup(this);
+    ToBackend(GetLayout())->DeallocateBindGroup(this);
 }
 
 // static
diff --git a/src/dawn/native/opengl/DeviceGL.cpp b/src/dawn/native/opengl/DeviceGL.cpp
index 5c24a8e..a75c7d8 100644
--- a/src/dawn/native/opengl/DeviceGL.cpp
+++ b/src/dawn/native/opengl/DeviceGL.cpp
@@ -17,7 +17,6 @@
 #include "dawn/common/Log.h"
 
 #include "dawn/native/BackendConnection.h"
-#include "dawn/native/BindGroupLayout.h"
 #include "dawn/native/ErrorData.h"
 #include "dawn/native/Instance.h"
 #include "dawn/native/opengl/BindGroupGL.h"
diff --git a/src/dawn/native/opengl/PipelineGL.cpp b/src/dawn/native/opengl/PipelineGL.cpp
index b3fad53..295aae3 100644
--- a/src/dawn/native/opengl/PipelineGL.cpp
+++ b/src/dawn/native/opengl/PipelineGL.cpp
@@ -19,7 +19,7 @@
 #include <string>
 
 #include "dawn/common/BitSetIterator.h"
-#include "dawn/native/BindGroupLayout.h"
+#include "dawn/native/BindGroupLayoutInternal.h"
 #include "dawn/native/Device.h"
 #include "dawn/native/Pipeline.h"
 #include "dawn/native/opengl/Forward.h"
@@ -113,7 +113,7 @@
 
         bool shouldUseFiltering;
         {
-            const BindGroupLayoutBase* bgl =
+            const BindGroupLayoutInternalBase* bgl =
                 layout->GetBindGroupLayout(combined.textureLocation.group);
             BindingIndex bindingIndex = bgl->GetBindingIndex(combined.textureLocation.binding);
 
@@ -127,7 +127,7 @@
             if (combined.usePlaceholderSampler) {
                 mPlaceholderSamplerUnits.push_back(textureUnit);
             } else {
-                const BindGroupLayoutBase* bgl =
+                const BindGroupLayoutInternalBase* bgl =
                     layout->GetBindGroupLayout(combined.samplerLocation.group);
                 BindingIndex bindingIndex = bgl->GetBindingIndex(combined.samplerLocation.binding);
 
diff --git a/src/dawn/native/opengl/PipelineLayoutGL.cpp b/src/dawn/native/opengl/PipelineLayoutGL.cpp
index c2d793d..850a5f4 100644
--- a/src/dawn/native/opengl/PipelineLayoutGL.cpp
+++ b/src/dawn/native/opengl/PipelineLayoutGL.cpp
@@ -15,7 +15,7 @@
 #include "dawn/native/opengl/PipelineLayoutGL.h"
 
 #include "dawn/common/BitSetIterator.h"
-#include "dawn/native/BindGroupLayout.h"
+#include "dawn/native/BindGroupLayoutInternal.h"
 #include "dawn/native/opengl/DeviceGL.h"
 
 namespace dawn::native::opengl {
@@ -29,7 +29,7 @@
     GLuint storageTextureIndex = 0;
 
     for (BindGroupIndex group : IterateBitSet(GetBindGroupLayoutsMask())) {
-        const BindGroupLayoutBase* bgl = GetBindGroupLayout(group);
+        const BindGroupLayoutInternalBase* bgl = GetBindGroupLayout(group);
         mIndexInfo[group].resize(bgl->GetBindingCount());
 
         for (BindingIndex bindingIndex{0}; bindingIndex < bgl->GetBindingCount(); ++bindingIndex) {
diff --git a/src/dawn/native/opengl/ShaderModuleGL.cpp b/src/dawn/native/opengl/ShaderModuleGL.cpp
index a8cb310..b0b48c4 100644
--- a/src/dawn/native/opengl/ShaderModuleGL.cpp
+++ b/src/dawn/native/opengl/ShaderModuleGL.cpp
@@ -17,7 +17,7 @@
 #include <sstream>
 #include <utility>
 
-#include "dawn/native/BindGroupLayout.h"
+#include "dawn/native/BindGroupLayoutInternal.h"
 #include "dawn/native/CacheRequest.h"
 #include "dawn/native/Pipeline.h"
 #include "dawn/native/TintUtils.h"
@@ -159,7 +159,7 @@
         GetEntryPoint(programmableStage.entryPoint).bindings;
     std::unordered_map<BindingPoint, BindingPoint> glBindings;
     for (BindGroupIndex group : IterateBitSet(layout->GetBindGroupLayoutsMask())) {
-        const BindGroupLayoutBase* bgl = layout->GetBindGroupLayout(group);
+        const BindGroupLayoutInternalBase* bgl = layout->GetBindGroupLayout(group);
         const auto& groupBindingInfo = moduleBindingInfo[group];
         for (const auto& [bindingNumber, bindingInfo] : groupBindingInfo) {
             BindingIndex bindingIndex = bgl->GetBindingIndex(bindingNumber);
diff --git a/src/dawn/native/vulkan/BindGroupVk.cpp b/src/dawn/native/vulkan/BindGroupVk.cpp
index fe2f4f0..6070ff2 100644
--- a/src/dawn/native/vulkan/BindGroupVk.cpp
+++ b/src/dawn/native/vulkan/BindGroupVk.cpp
@@ -153,8 +153,7 @@
 
 void BindGroup::DestroyImpl() {
     BindGroupBase::DestroyImpl();
-    ToBackend(GetLayout()->GetInternalBindGroupLayout())
-        ->DeallocateBindGroup(this, &mDescriptorSetAllocation);
+    ToBackend(GetLayout())->DeallocateBindGroup(this, &mDescriptorSetAllocation);
 }
 
 VkDescriptorSet BindGroup::GetHandle() const {
diff --git a/src/dawn/native/vulkan/PipelineLayoutVk.cpp b/src/dawn/native/vulkan/PipelineLayoutVk.cpp
index 7bbba52..6db5739 100644
--- a/src/dawn/native/vulkan/PipelineLayoutVk.cpp
+++ b/src/dawn/native/vulkan/PipelineLayoutVk.cpp
@@ -40,8 +40,7 @@
     std::array<VkDescriptorSetLayout, kMaxBindGroups> setLayouts;
     std::array<const CachedObject*, kMaxBindGroups> cachedObjects;
     for (BindGroupIndex setIndex : IterateBitSet(GetBindGroupLayoutsMask())) {
-        const BindGroupLayoutInternalBase* bindGroupLayout =
-            GetBindGroupLayout(setIndex)->GetInternalBindGroupLayout();
+        const BindGroupLayoutInternalBase* bindGroupLayout = GetBindGroupLayout(setIndex);
         setLayouts[numSetLayouts] = ToBackend(bindGroupLayout)->GetHandle();
         cachedObjects[numSetLayouts] = bindGroupLayout;
         numSetLayouts++;
diff --git a/src/dawn/native/vulkan/ShaderModuleVk.cpp b/src/dawn/native/vulkan/ShaderModuleVk.cpp
index e5fe7c9..c727acc 100644
--- a/src/dawn/native/vulkan/ShaderModuleVk.cpp
+++ b/src/dawn/native/vulkan/ShaderModuleVk.cpp
@@ -215,8 +215,7 @@
         GetEntryPoint(programmableStage.entryPoint.c_str()).bindings;
 
     for (BindGroupIndex group : IterateBitSet(layout->GetBindGroupLayoutsMask())) {
-        const BindGroupLayout* bgl =
-            ToBackend(layout->GetBindGroupLayout(group)->GetInternalBindGroupLayout());
+        const BindGroupLayout* bgl = ToBackend(layout->GetBindGroupLayout(group));
         const auto& groupBindingInfo = moduleBindingInfo[group];
         for (const auto& [binding, _] : groupBindingInfo) {
             BindingIndex bindingIndex = bgl->GetBindingIndex(binding);
@@ -235,7 +234,7 @@
     // TODO(dawn:1082): Replace this block with BuildExternalTextureTransformBindings.
     tint::ExternalTextureOptions externalTextureOptions;
     for (BindGroupIndex i : IterateBitSet(layout->GetBindGroupLayoutsMask())) {
-        const BindGroupLayoutBase* bgl = layout->GetBindGroupLayout(i);
+        const BindGroupLayoutInternalBase* bgl = layout->GetBindGroupLayout(i);
 
         for (const auto& [_, expansion] : bgl->GetExternalTextureBindingExpansionMap()) {
             externalTextureOptions
diff --git a/src/dawn/tests/unittests/native/mocks/BindGroupMock.cpp b/src/dawn/tests/unittests/native/mocks/BindGroupMock.cpp
index 457fe70..f923984 100644
--- a/src/dawn/tests/unittests/native/mocks/BindGroupMock.cpp
+++ b/src/dawn/tests/unittests/native/mocks/BindGroupMock.cpp
@@ -17,7 +17,7 @@
 namespace dawn::native {
 
 BindGroupMock::BindGroupMock(DeviceMock* device, const BindGroupDescriptor* descriptor)
-    : BindGroupDataHolder(descriptor->layout->GetBindingDataSize()),
+    : BindGroupDataHolder(descriptor->layout->GetInternalBindGroupLayout()->GetBindingDataSize()),
       BindGroupBase(device, descriptor, mBindingDataAllocation) {
     ON_CALL(*this, DestroyImpl).WillByDefault([this] { this->BindGroupBase::DestroyImpl(); });
 }