Revert "Cache VkFramebuffers"

This reverts commit a5458565999008b994f4150e257afabb934ac14d.

Bug: 416088623
Original change's description:
> Cache VkFramebuffers
>
> It seems that creation of VkFramebuffers is more expensive than expected
> on mobile devices, so this introduces a framebuffer cache that mimics
> the existing Vulkan Render Pass cache in hopes of reducing that
> overhead.
>
> Bug: 416088623
> Change-Id: I89bc608fc66b088d267c0263f79ed93fcdbe890a
> Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/243636
> Reviewed-by: Corentin Wallez <cwallez@chromium.org>
> Reviewed-by: Loko Kung <lokokung@google.com>
> Commit-Queue: Brandon Jones <bajones@chromium.org>

# Not skipping CQ checks because original CL landed > 1 day ago.

Bug: 416088623
Change-Id: I2703501475fced4a4fa6f702997b23641d5d2c7f
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/247115
Reviewed-by: Peter McNeeley <petermcneeley@google.com>
Commit-Queue: Loko Kung <lokokung@google.com>
Reviewed-by: Loko Kung <lokokung@google.com>
diff --git a/src/dawn/native/BUILD.gn b/src/dawn/native/BUILD.gn
index e5d23d4..6b7226d 100644
--- a/src/dawn/native/BUILD.gn
+++ b/src/dawn/native/BUILD.gn
@@ -836,8 +836,6 @@
       "vulkan/FencedDeleter.cpp",
       "vulkan/FencedDeleter.h",
       "vulkan/Forward.h",
-      "vulkan/FramebufferCache.cpp",
-      "vulkan/FramebufferCache.h",
       "vulkan/PhysicalDeviceVk.cpp",
       "vulkan/PhysicalDeviceVk.h",
       "vulkan/PipelineCacheVk.cpp",
diff --git a/src/dawn/native/CMakeLists.txt b/src/dawn/native/CMakeLists.txt
index b49ffc9..1b69194 100644
--- a/src/dawn/native/CMakeLists.txt
+++ b/src/dawn/native/CMakeLists.txt
@@ -708,7 +708,6 @@
         "vulkan/ExternalHandle.h"
         "vulkan/FencedDeleter.h"
         "vulkan/Forward.h"
-        "vulkan/FramebufferCache.h"
         "vulkan/PhysicalDeviceVk.h"
         "vulkan/PipelineVk.h"
         "vulkan/PipelineCacheVk.h"
@@ -750,7 +749,6 @@
         "vulkan/DescriptorSetAllocator.cpp"
         "vulkan/DeviceVk.cpp"
         "vulkan/FencedDeleter.cpp"
-        "vulkan/FramebufferCache.cpp"
         "vulkan/PhysicalDeviceVk.cpp"
         "vulkan/PipelineVk.cpp"
         "vulkan/PipelineCacheVk.cpp"
diff --git a/src/dawn/native/Toggles.cpp b/src/dawn/native/Toggles.cpp
index 5fe3040..21bd277 100644
--- a/src/dawn/native/Toggles.cpp
+++ b/src/dawn/native/Toggles.cpp
@@ -659,12 +659,6 @@
       "Compute the range of the index with Integer Range Analysis in the robustness transform and "
       "skip doing index clamping when the out of bound access cannot happen.",
       "https://crbug.com/348701956", ToggleStage::Device}},
-    {Toggle::VulkanDisableFramebufferCache,
-     {"vulkan_disable_framebuffer_cache",
-      "Prevents caching of VkFramebuffer objects. When active a new framebuffer will be created "
-      "for every render pass. Enabled by default on Qualcomm GPUs, which have issues with "
-      "framebuffer reuse.",
-      "https://crbug.com/416088623", ToggleStage::Device}},
     {Toggle::NoWorkaroundSampleMaskBecomesZeroForAllButLastColorTarget,
      {"no_workaround_sample_mask_becomes_zero_for_all_but_last_color_target",
       "MacOS 12.0+ Intel has a bug where the sample mask is only applied for the last color "
diff --git a/src/dawn/native/Toggles.h b/src/dawn/native/Toggles.h
index fa3a385..e2ea5c6 100644
--- a/src/dawn/native/Toggles.h
+++ b/src/dawn/native/Toggles.h
@@ -156,7 +156,6 @@
     VulkanDirectVariableAccessTransformHandle,
     VulkanAddWorkToEmptyResolvePass,
     EnableIntegerRangeAnalysisInRobustness,
-    VulkanDisableFramebufferCache,
 
     // Unresolved issues.
     NoWorkaroundSampleMaskBecomesZeroForAllButLastColorTarget,
diff --git a/src/dawn/native/vulkan/CommandBufferVk.cpp b/src/dawn/native/vulkan/CommandBufferVk.cpp
index c02b390..25539fe 100644
--- a/src/dawn/native/vulkan/CommandBufferVk.cpp
+++ b/src/dawn/native/vulkan/CommandBufferVk.cpp
@@ -45,7 +45,6 @@
 #include "dawn/native/vulkan/ComputePipelineVk.h"
 #include "dawn/native/vulkan/DeviceVk.h"
 #include "dawn/native/vulkan/FencedDeleter.h"
-#include "dawn/native/vulkan/FramebufferCache.h"
 #include "dawn/native/vulkan/PhysicalDeviceVk.h"
 #include "dawn/native/vulkan/PipelineLayoutVk.h"
 #include "dawn/native/vulkan/QuerySetVk.h"
@@ -453,15 +452,15 @@
         renderPassVK = renderPassInfo.renderPass;
     }
 
-    // Query a framebuffer from the cache and gather the clear values for the attachments at the
-    // same time.
-    FramebufferCacheQuery framebufferQuery;
+    // Create a framebuffer that will be used once for the render pass and gather the clear
+    // values for the attachments at the same time.
     std::array<VkClearValue, kMaxColorAttachments + 1> clearValues;
     VkFramebuffer framebuffer = VK_NULL_HANDLE;
+    uint32_t attachmentCount = 0;
     {
-        framebufferQuery.SetRenderPass(renderPassVK, renderPass->width, renderPass->height);
-
         // Fill in the attachment info that will be chained in the framebuffer create info.
+        std::array<VkImageView, kMaxColorAttachments * 2 + 1> attachments;
+
         for (auto i : renderPass->attachmentState->GetColorAttachmentsMask()) {
             auto& attachmentInfo = renderPass->colorAttachments[i];
             TextureView* view = ToBackend(attachmentInfo.view.Get());
@@ -469,14 +468,13 @@
                 continue;
             }
 
-            uint32_t attachmentIndex;
             if (view->GetDimension() == wgpu::TextureViewDimension::e3D) {
                 VkImageView handleFor2DViewOn3D;
                 DAWN_TRY_ASSIGN(handleFor2DViewOn3D,
                                 view->GetOrCreate2DViewOn3D(attachmentInfo.depthSlice));
-                attachmentIndex = framebufferQuery.AddAttachment(handleFor2DViewOn3D);
+                attachments[attachmentCount] = handleFor2DViewOn3D;
             } else {
-                attachmentIndex = framebufferQuery.AddAttachment(view->GetHandle());
+                attachments[attachmentCount] = view->GetHandle();
             }
 
             switch (view->GetFormat().GetAspectInfo(Aspect::Color).baseType) {
@@ -484,7 +482,7 @@
                     const std::array<float, 4> appliedClearColor =
                         ConvertToFloatColor(attachmentInfo.clearColor);
                     for (uint32_t j = 0; j < 4; ++j) {
-                        clearValues[attachmentIndex].color.float32[j] = appliedClearColor[j];
+                        clearValues[attachmentCount].color.float32[j] = appliedClearColor[j];
                     }
                     break;
                 }
@@ -492,7 +490,7 @@
                     const std::array<uint32_t, 4> appliedClearColor =
                         ConvertToUnsignedIntegerColor(attachmentInfo.clearColor);
                     for (uint32_t j = 0; j < 4; ++j) {
-                        clearValues[attachmentIndex].color.uint32[j] = appliedClearColor[j];
+                        clearValues[attachmentCount].color.uint32[j] = appliedClearColor[j];
                     }
                     break;
                 }
@@ -500,52 +498,55 @@
                     const std::array<int32_t, 4> appliedClearColor =
                         ConvertToSignedIntegerColor(attachmentInfo.clearColor);
                     for (uint32_t j = 0; j < 4; ++j) {
-                        clearValues[attachmentIndex].color.int32[j] = appliedClearColor[j];
+                        clearValues[attachmentCount].color.int32[j] = appliedClearColor[j];
                     }
                     break;
                 }
             }
+            attachmentCount++;
         }
 
         if (renderPass->attachmentState->HasDepthStencilAttachment()) {
             auto& attachmentInfo = renderPass->depthStencilAttachment;
             TextureView* view = ToBackend(attachmentInfo.view.Get());
 
-            uint32_t attachmentIndex = framebufferQuery.AddAttachment(view->GetHandle());
+            attachments[attachmentCount] = view->GetHandle();
 
-            clearValues[attachmentIndex].depthStencil.depth = attachmentInfo.clearDepth;
-            clearValues[attachmentIndex].depthStencil.stencil = attachmentInfo.clearStencil;
+            clearValues[attachmentCount].depthStencil.depth = attachmentInfo.clearDepth;
+            clearValues[attachmentCount].depthStencil.stencil = attachmentInfo.clearStencil;
+
+            attachmentCount++;
         }
 
         for (auto i : renderPass->attachmentState->GetColorAttachmentsMask()) {
             if (renderPass->colorAttachments[i].resolveTarget != nullptr) {
                 TextureView* view = ToBackend(renderPass->colorAttachments[i].resolveTarget.Get());
-                framebufferQuery.AddAttachment(view->GetHandle());
+
+                attachments[attachmentCount] = view->GetHandle();
+
+                attachmentCount++;
             }
         }
 
-        DAWN_TRY_ASSIGN(framebuffer,
-                        device->GetFramebufferCache()->GetOrCreate(
-                            framebufferQuery,
-                            [&](FramebufferCacheQuery& query) -> ResultOrError<VkFramebuffer> {
-                                VkFramebufferCreateInfo createInfo;
-                                createInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
-                                createInfo.pNext = nullptr;
-                                createInfo.flags = 0;
-                                createInfo.renderPass = query.renderPass;
-                                createInfo.attachmentCount = query.attachmentCount;
-                                createInfo.pAttachments = AsVkArray(query.attachments.data());
-                                createInfo.width = query.width;
-                                createInfo.height = query.height;
-                                createInfo.layers = 1;
+        // Chain attachments and create the framebuffer
+        VkFramebufferCreateInfo createInfo;
+        createInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
+        createInfo.pNext = nullptr;
+        createInfo.flags = 0;
+        createInfo.renderPass = renderPassVK;
+        createInfo.attachmentCount = attachmentCount;
+        createInfo.pAttachments = AsVkArray(attachments.data());
+        createInfo.width = renderPass->width;
+        createInfo.height = renderPass->height;
+        createInfo.layers = 1;
 
-                                VkFramebuffer framebuffer;
-                                DAWN_TRY(CheckVkSuccess(
-                                    device->fn.CreateFramebuffer(device->GetVkDevice(), &createInfo,
-                                                                 nullptr, &*framebuffer),
-                                    "CreateFramebuffer"));
-                                return framebuffer;
-                            }));
+        DAWN_TRY(CheckVkSuccess(device->fn.CreateFramebuffer(device->GetVkDevice(), &createInfo,
+                                                             nullptr, &*framebuffer),
+                                "CreateFramebuffer"));
+
+        // We don't reuse VkFramebuffers so mark the framebuffer for deletion as soon as the
+        // commands currently being recorded are finished.
+        device->GetFencedDeleter()->DeleteWhenUnused(framebuffer);
     }
 
     VkRenderPassBeginInfo beginInfo;
@@ -557,7 +558,7 @@
     beginInfo.renderArea.offset.y = 0;
     beginInfo.renderArea.extent.width = renderPass->width;
     beginInfo.renderArea.extent.height = renderPass->height;
-    beginInfo.clearValueCount = framebufferQuery.attachmentCount;
+    beginInfo.clearValueCount = attachmentCount;
     beginInfo.pClearValues = clearValues.data();
 
     if (renderPass->attachmentState->GetExpandResolveInfo().attachmentsToExpandResolve.any()) {
diff --git a/src/dawn/native/vulkan/DeviceVk.cpp b/src/dawn/native/vulkan/DeviceVk.cpp
index 8ed06fe..ca84294 100644
--- a/src/dawn/native/vulkan/DeviceVk.cpp
+++ b/src/dawn/native/vulkan/DeviceVk.cpp
@@ -50,7 +50,6 @@
 #include "dawn/native/vulkan/CommandBufferVk.h"
 #include "dawn/native/vulkan/ComputePipelineVk.h"
 #include "dawn/native/vulkan/FencedDeleter.h"
-#include "dawn/native/vulkan/FramebufferCache.h"
 #include "dawn/native/vulkan/PhysicalDeviceVk.h"
 #include "dawn/native/vulkan/PipelineCacheVk.h"
 #include "dawn/native/vulkan/PipelineLayoutVk.h"
@@ -142,10 +141,6 @@
         functions->CmdDrawIndexedIndirect = NoopDrawFunction<PFN_vkCmdDrawIndexedIndirect>::Fun;
     }
 
-    mFramebufferCache = std::make_unique<FramebufferCache>(
-        this, IsToggleEnabled(Toggle::VulkanDisableFramebufferCache)
-                  ? 0
-                  : FramebufferCache::kDefaultCapacity);
     mRenderPassCache = std::make_unique<RenderPassCache>(this);
 
     VkDeviceSize heapBlockSize =
@@ -393,10 +388,6 @@
     return *mDeleter;
 }
 
-FramebufferCache* Device::GetFramebufferCache() const {
-    return mFramebufferCache.get();
-}
-
 RenderPassCache* Device::GetRenderPassCache() const {
     return mRenderPassCache.get();
 }
@@ -953,9 +944,8 @@
     // Allow recycled memory to be deleted.
     GetResourceMemoryAllocator()->FreeRecycledMemory();
 
-    // The VkFramebuffers and VkRenderPasses in the cache can be destroyed immediately since all
-    // commands referring to them are guaranteed to be finished executing.
-    mFramebufferCache = nullptr;
+    // The VkRenderPasses in the cache can be destroyed immediately since all commands referring
+    // to them are guaranteed to be finished executing.
     mRenderPassCache = nullptr;
 
     // Destroy the VkPipelineCache before VkDevice.
diff --git a/src/dawn/native/vulkan/DeviceVk.h b/src/dawn/native/vulkan/DeviceVk.h
index 690e9e9..547e362 100644
--- a/src/dawn/native/vulkan/DeviceVk.h
+++ b/src/dawn/native/vulkan/DeviceVk.h
@@ -53,7 +53,6 @@
 
 class BufferUploader;
 class FencedDeleter;
-class FramebufferCache;
 class RenderPassCache;
 class ResourceMemoryAllocator;
 
@@ -77,7 +76,6 @@
     uint32_t GetGraphicsQueueFamily() const;
 
     MutexProtected<FencedDeleter>& GetFencedDeleter() const;
-    FramebufferCache* GetFramebufferCache() const;
     RenderPassCache* GetRenderPassCache() const;
     MutexProtected<ResourceMemoryAllocator>& GetResourceMemoryAllocator() const;
     external_semaphore::Service* GetExternalSemaphoreService() const;
@@ -203,7 +201,6 @@
         mDescriptorAllocatorsPendingDeallocation;
     std::unique_ptr<MutexProtected<FencedDeleter>> mDeleter;
     std::unique_ptr<MutexProtected<ResourceMemoryAllocator>> mResourceMemoryAllocator;
-    std::unique_ptr<FramebufferCache> mFramebufferCache;
     std::unique_ptr<RenderPassCache> mRenderPassCache;
 
     std::unique_ptr<external_memory::Service> mExternalMemoryService;
diff --git a/src/dawn/native/vulkan/FramebufferCache.cpp b/src/dawn/native/vulkan/FramebufferCache.cpp
deleted file mode 100644
index 58bbb73..0000000
--- a/src/dawn/native/vulkan/FramebufferCache.cpp
+++ /dev/null
@@ -1,100 +0,0 @@
-// Copyright 2025 The Dawn & Tint Authors
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-//
-// 1. Redistributions of source code must retain the above copyright notice, this
-//    list of conditions and the following disclaimer.
-//
-// 2. Redistributions in binary form must reproduce the above copyright notice,
-//    this list of conditions and the following disclaimer in the documentation
-//    and/or other materials provided with the distribution.
-//
-// 3. Neither the name of the copyright holder nor the names of its
-//    contributors may be used to endorse or promote products derived from
-//    this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#include "dawn/native/vulkan/FramebufferCache.h"
-
-#include "absl/container/inlined_vector.h"
-#include "dawn/common/HashUtils.h"
-#include "dawn/common/Range.h"
-#include "dawn/common/vulkan_platform.h"
-#include "dawn/native/vulkan/DeviceVk.h"
-#include "dawn/native/vulkan/FencedDeleter.h"
-#include "dawn/native/vulkan/VulkanError.h"
-
-namespace dawn::native::vulkan {
-
-// FramebufferCacheQuery
-
-void FramebufferCacheQuery::SetRenderPass(VkRenderPass pass,
-                                          uint32_t passWidth,
-                                          uint32_t passHeight) {
-    renderPass = pass;
-    width = passWidth;
-    height = passHeight;
-}
-
-uint32_t FramebufferCacheQuery::AddAttachment(VkImageView attachment) {
-    attachments[attachmentCount] = attachment;
-    return attachmentCount++;
-}
-
-// FramebufferCache
-
-FramebufferCache::FramebufferCache(Device* device, size_t capacity)
-    : FramebufferCache::Base(capacity), mDevice(device) {}
-
-FramebufferCache::~FramebufferCache() {
-    mCache.Use([this](auto cache) {
-        for (auto [_, framebuffer] : cache->list) {
-            mDevice->fn.DestroyFramebuffer(mDevice->GetVkDevice(), framebuffer, nullptr);
-        }
-    });
-}
-
-void FramebufferCache::EvictedFromCache(const VkFramebuffer& framebuffer) {
-    mDevice->GetFencedDeleter()->DeleteWhenUnused(framebuffer);
-}
-
-size_t FramebufferCacheFuncs::operator()(const FramebufferCacheQuery& query) const {
-    size_t hash = Hash(query.renderPass.GetHandle());
-
-    HashCombine(&hash, query.width, query.height, query.attachmentCount);
-
-    for (uint32_t i = 0; i < query.attachmentCount; ++i) {
-        HashCombine(&hash, query.attachments[i].GetHandle());
-    }
-
-    return hash;
-}
-
-bool FramebufferCacheFuncs::operator()(const FramebufferCacheQuery& a,
-                                       const FramebufferCacheQuery& b) const {
-    if (a.renderPass != b.renderPass || a.width != b.width || a.height != b.height ||
-        a.attachmentCount != b.attachmentCount) {
-        return false;
-    }
-
-    for (uint32_t i = 0; i < a.attachmentCount; ++i) {
-        if (a.attachments[i] != b.attachments[i]) {
-            return false;
-        }
-    }
-
-    return true;
-}
-
-}  // namespace dawn::native::vulkan
diff --git a/src/dawn/native/vulkan/FramebufferCache.h b/src/dawn/native/vulkan/FramebufferCache.h
deleted file mode 100644
index 8944004..0000000
--- a/src/dawn/native/vulkan/FramebufferCache.h
+++ /dev/null
@@ -1,93 +0,0 @@
-// Copyright 2025 The Dawn & Tint Authors
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-//
-// 1. Redistributions of source code must retain the above copyright notice, this
-//    list of conditions and the following disclaimer.
-//
-// 2. Redistributions in binary form must reproduce the above copyright notice,
-//    this list of conditions and the following disclaimer in the documentation
-//    and/or other materials provided with the distribution.
-//
-// 3. Neither the name of the copyright holder nor the names of its
-//    contributors may be used to endorse or promote products derived from
-//    this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#ifndef SRC_DAWN_NATIVE_VULKAN_FRAMEBUFFERCACHE_H_
-#define SRC_DAWN_NATIVE_VULKAN_FRAMEBUFFERCACHE_H_
-
-#include <array>
-#include <list>
-#include <mutex>
-#include <utility>
-
-#include "absl/container/flat_hash_map.h"
-#include "dawn/common/Constants.h"
-#include "dawn/common/LRUCache.h"
-#include "dawn/common/vulkan_platform.h"
-#include "dawn/native/Error.h"
-#include "dawn/native/dawn_platform.h"
-#include "partition_alloc/pointers/raw_ptr.h"
-
-namespace dawn::native::vulkan {
-
-class Device;
-
-// A key to query the FramebufferCache
-struct FramebufferCacheQuery {
-    // Use these helpers to build the query, they make sure all relevant data is initialized and
-    // masks set.
-    void SetRenderPass(VkRenderPass pass, uint32_t passWidth, uint32_t passHeight);
-    uint32_t AddAttachment(VkImageView attachment);
-
-    VkRenderPass renderPass;
-    uint32_t width;
-    uint32_t height;
-
-    std::array<VkImageView, kMaxColorAttachments * 2 + 1> attachments;
-    uint32_t attachmentCount = 0;
-};
-
-// Implements the functors necessary for to use RenderPassCacheQueries as absl::flat_hash_map keys.
-struct FramebufferCacheFuncs {
-    size_t operator()(const FramebufferCacheQuery& query) const;
-    bool operator()(const FramebufferCacheQuery& a, const FramebufferCacheQuery& b) const;
-};
-
-// A LRU Cache of VkFramebuffers so that we reduce the need to re-create framebuffers for every
-// render pass. We always arrange the order of attachments in "color-depthstencil-resolve" order
-// when creating render pass and framebuffer so that we can always make sure the order of
-// attachments in the rendering pipeline matches the one of the framebuffer.
-// All the operations on FramebufferCache are guaranteed to be thread-safe.
-class FramebufferCache final
-    : public LRUCache<FramebufferCacheQuery, VkFramebuffer, ErrorData, FramebufferCacheFuncs> {
-    using Base = LRUCache<FramebufferCacheQuery, VkFramebuffer, ErrorData, FramebufferCacheFuncs>;
-
-  public:
-    static const size_t kDefaultCapacity = 32;
-    explicit FramebufferCache(Device* device, size_t capacity = kDefaultCapacity);
-    ~FramebufferCache() override;
-
-    void EvictedFromCache(const VkFramebuffer& value) override;
-
-  private:
-    // We use a raw pointer to the device here because the cache is always owned by the device
-    // and hence should always be valid.
-    raw_ptr<Device> mDevice;
-};
-
-}  // namespace dawn::native::vulkan
-
-#endif  // SRC_DAWN_NATIVE_VULKAN_FRAMEBUFFERCACHE_H_
diff --git a/src/dawn/native/vulkan/PhysicalDeviceVk.cpp b/src/dawn/native/vulkan/PhysicalDeviceVk.cpp
index 552d2ef..a3bb0b0 100644
--- a/src/dawn/native/vulkan/PhysicalDeviceVk.cpp
+++ b/src/dawn/native/vulkan/PhysicalDeviceVk.cpp
@@ -817,9 +817,6 @@
         // chromium:407109052: Qualcomm devices have a bug where the spirv extended op NClamp
         // modifies other components of a vector when one of the components is nan.
         deviceToggles->Default(Toggle::VulkanScalarizeClampBuiltin, true);
-
-        // chromium:416088623: Some Qualcomm devices have issues with reusing VkFramebuffers.
-        deviceToggles->Default(Toggle::VulkanDisableFramebufferCache, true);
     }
 
     if (IsAndroidARM()) {
@@ -845,11 +842,6 @@
         deviceToggles->Default(Toggle::IgnoreImportedAHardwareBufferVulkanImageSize, true);
     }
 
-    if (IsAndroidSwiftshader()) {
-        // Disable framebuffer caching to avoid timeout errors seen on some Android emulators.
-        deviceToggles->Default(Toggle::VulkanDisableFramebufferCache, true);
-    }
-
     if (IsIntelMesa() && gpu_info::IsIntelGen12LP(GetVendorId(), GetDeviceId())) {
         // dawn:1688: Intel Mesa driver has a bug about reusing the VkDeviceMemory that was
         // previously bound to a 2D VkImage. To work around that bug we have to disable the resource
@@ -1041,14 +1033,6 @@
     return false;
 }
 
-bool PhysicalDevice::IsAndroidSwiftshader() const {
-#if DAWN_PLATFORM_IS(ANDROID)
-    return gpu_info::IsGoogle(GetVendorId());
-#else
-    return false;
-#endif
-}
-
 uint32_t PhysicalDevice::FindDefaultComputeSubgroupSize() const {
     if (!mDeviceInfo.HasExt(DeviceExt::SubgroupSizeControl)) {
         return 0;
diff --git a/src/dawn/native/vulkan/PhysicalDeviceVk.h b/src/dawn/native/vulkan/PhysicalDeviceVk.h
index 02d6a7f..0d15851 100644
--- a/src/dawn/native/vulkan/PhysicalDeviceVk.h
+++ b/src/dawn/native/vulkan/PhysicalDeviceVk.h
@@ -66,7 +66,6 @@
     bool IsAndroidSamsung() const;
     bool IsIntelMesa() const;
     bool IsAndroidHuawei() const;
-    bool IsAndroidSwiftshader() const;
 
     uint32_t GetDefaultComputeSubgroupSize() const;