From df6dffa30baefd9f1e73399c632ab4e5f6475bab Mon Sep 17 00:00:00 2001
From: Byte <byteslice@airmail.cc>
Date: Thu, 6 Oct 2022 20:59:40 +0200
Subject: [PATCH] vulkan_blitter: Fix pool allocation double free.

---
 .../renderer_vulkan/vk_blit_screen.cpp        | 13 ++++++++----
 .../renderer_vulkan/vk_blit_screen.h          |  2 +-
 src/video_core/vulkan_common/vulkan_wrapper.h | 20 -------------------
 3 files changed, 10 insertions(+), 25 deletions(-)

diff --git a/src/video_core/renderer_vulkan/vk_blit_screen.cpp b/src/video_core/renderer_vulkan/vk_blit_screen.cpp
index 444c29f68..cb7fa2078 100644
--- a/src/video_core/renderer_vulkan/vk_blit_screen.cpp
+++ b/src/video_core/renderer_vulkan/vk_blit_screen.cpp
@@ -145,6 +145,11 @@ VkSemaphore BlitScreen::Draw(const Tegra::FramebufferConfig& framebuffer,
     // Finish any pending renderpass
     scheduler.RequestOutsideRenderPassOperationContext();
 
+    if (const auto swapchain_images = swapchain.GetImageCount(); swapchain_images != image_count) {
+        image_count = swapchain_images;
+        Recreate();
+    }
+
     const std::size_t image_index = swapchain.GetImageIndex();
 
     scheduler.Wait(resource_ticks[image_index]);
@@ -448,15 +453,15 @@ vk::Framebuffer BlitScreen::CreateFramebuffer(const VkImageView& image_view, VkE
 
 void BlitScreen::CreateStaticResources() {
     CreateShaders();
+    CreateSampler();
+}
+
+void BlitScreen::CreateDynamicResources() {
     CreateSemaphores();
     CreateDescriptorPool();
     CreateDescriptorSetLayout();
     CreateDescriptorSets();
     CreatePipelineLayout();
-    CreateSampler();
-}
-
-void BlitScreen::CreateDynamicResources() {
     CreateRenderPass();
     CreateFramebuffers();
     CreateGraphicsPipeline();
diff --git a/src/video_core/renderer_vulkan/vk_blit_screen.h b/src/video_core/renderer_vulkan/vk_blit_screen.h
index b8c67bef0..29e2ea925 100644
--- a/src/video_core/renderer_vulkan/vk_blit_screen.h
+++ b/src/video_core/renderer_vulkan/vk_blit_screen.h
@@ -109,7 +109,7 @@ private:
     MemoryAllocator& memory_allocator;
     Swapchain& swapchain;
     Scheduler& scheduler;
-    const std::size_t image_count;
+    std::size_t image_count;
     const ScreenInfo& screen_info;
 
     vk::ShaderModule vertex_shader;
diff --git a/src/video_core/vulkan_common/vulkan_wrapper.h b/src/video_core/vulkan_common/vulkan_wrapper.h
index 795f16bfb..1b3f493bd 100644
--- a/src/video_core/vulkan_common/vulkan_wrapper.h
+++ b/src/video_core/vulkan_common/vulkan_wrapper.h
@@ -519,9 +519,7 @@ public:
           dld{rhs.dld} {}
 
     /// Assign an allocation transfering ownership from another allocation.
-    /// Releases any previously held allocation.
     PoolAllocations& operator=(PoolAllocations&& rhs) noexcept {
-        Release();
         allocations = std::move(rhs.allocations);
         num = rhs.num;
         device = rhs.device;
@@ -530,11 +528,6 @@ public:
         return *this;
     }
 
-    /// Destroys any held allocation.
-    ~PoolAllocations() {
-        Release();
-    }
-
     /// Returns the number of allocations.
     std::size_t size() const noexcept {
         return num;
@@ -557,19 +550,6 @@ public:
     }
 
 private:
-    /// Destroys the held allocations if they exist.
-    void Release() noexcept {
-        if (!allocations) {
-            return;
-        }
-        const Span<AllocationType> span(allocations.get(), num);
-        const VkResult result = Free(device, pool, span, *dld);
-        // There's no way to report errors from a destructor.
-        if (result != VK_SUCCESS) {
-            std::terminate();
-        }
-    }
-
     std::unique_ptr<AllocationType[]> allocations;
     std::size_t num = 0;
     VkDevice device = nullptr;