From 36f261edefd2e16d34f2726f0a0295e089ed1c17 Mon Sep 17 00:00:00 2001
From: ameerj <52414509+ameerj@users.noreply.github.com>
Date: Tue, 21 Sep 2021 22:22:24 -0400
Subject: [PATCH] vk_texture_cache: Simplify scaled image management

---
 .../renderer_vulkan/vk_texture_cache.cpp      | 111 ++++--------------
 .../renderer_vulkan/vk_texture_cache.h        |  30 ++---
 2 files changed, 34 insertions(+), 107 deletions(-)

diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp
index a34cd31f0e..5b4f51a317 100644
--- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp
@@ -996,17 +996,14 @@ u64 TextureCacheRuntime::GetDeviceLocalMemory() const {
     return device.GetDeviceLocalMemory();
 }
 
-void TextureCacheRuntime::TickFrame() {
-    prescaled_images.Tick();
-    prescaled_commits.Tick();
-}
+void TextureCacheRuntime::TickFrame() {}
 
 Image::Image(TextureCacheRuntime& runtime_, const ImageInfo& info_, GPUVAddr gpu_addr_,
              VAddr cpu_addr_)
     : VideoCommon::ImageBase(info_, gpu_addr_, cpu_addr_), scheduler{&runtime_.scheduler},
-      image(MakeImage(runtime_.device, info)),
-      commit(runtime_.memory_allocator.Commit(image, MemoryUsage::DeviceLocal)),
-      aspect_mask(ImageAspectMask(info.format)), runtime{&runtime_} {
+      runtime{&runtime_}, original_image(MakeImage(runtime_.device, info)),
+      commit(runtime_.memory_allocator.Commit(original_image, MemoryUsage::DeviceLocal)),
+      aspect_mask(ImageAspectMask(info.format)) {
     if (IsPixelFormatASTC(info.format) && !runtime->device.IsOptimalAstcSupported()) {
         if (Settings::values.accelerate_astc.GetValue()) {
             flags |= VideoCommon::ImageFlagBits::AcceleratedUpload;
@@ -1015,13 +1012,14 @@ Image::Image(TextureCacheRuntime& runtime_, const ImageInfo& info_, GPUVAddr gpu
         }
     }
     if (runtime->device.HasDebuggingToolAttached()) {
-        image.SetObjectNameEXT(VideoCommon::Name(*this).c_str());
+        original_image.SetObjectNameEXT(VideoCommon::Name(*this).c_str());
     }
     static constexpr VkImageViewUsageCreateInfo storage_image_view_usage_create_info{
         .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO,
         .pNext = nullptr,
         .usage = VK_IMAGE_USAGE_STORAGE_BIT,
     };
+    current_image = *original_image;
     if (IsPixelFormatASTC(info.format) && !runtime->device.IsOptimalAstcSupported()) {
         const auto& device = runtime->device.GetLogical();
         storage_image_views.reserve(info.resources.levels);
@@ -1030,7 +1028,7 @@ Image::Image(TextureCacheRuntime& runtime_, const ImageInfo& info_, GPUVAddr gpu
                 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
                 .pNext = &storage_image_view_usage_create_info,
                 .flags = 0,
-                .image = *image,
+                .image = *original_image,
                 .viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY,
                 .format = VK_FORMAT_A8B8G8R8_UNORM_PACK32,
                 .components{
@@ -1059,12 +1057,12 @@ void Image::UploadMemory(const StagingBufferRef& map, std::span<const BufferImag
     // TODO: Move this to another API
     const bool is_rescaled = True(flags & ImageFlagBits::Rescaled);
     if (is_rescaled) {
-        ScaleDown(true);
+        ScaleDown();
     }
     scheduler->RequestOutsideRenderPassOperationContext();
     std::vector vk_copies = TransformBufferImageCopies(copies, map.offset, aspect_mask);
     const VkBuffer src_buffer = map.buffer;
-    const VkImage vk_image = *image;
+    const VkImage vk_image = *original_image;
     const VkImageAspectFlags vk_aspect_mask = aspect_mask;
     const bool is_initialized = std::exchange(initialized, true);
     scheduler->Record([src_buffer, vk_image, vk_aspect_mask, is_initialized,
@@ -1072,18 +1070,14 @@ void Image::UploadMemory(const StagingBufferRef& map, std::span<const BufferImag
         CopyBufferToImage(cmdbuf, src_buffer, vk_image, vk_aspect_mask, is_initialized, vk_copies);
     });
     if (is_rescaled) {
-        ScaleUp(true);
+        ScaleUp();
     }
 }
 
 void Image::DownloadMemory(const StagingBufferRef& map, std::span<const BufferImageCopy> copies) {
-    const bool is_rescaled = True(flags & ImageFlagBits::Rescaled);
-    if (is_rescaled) {
-        ScaleDown(true);
-    }
     std::vector vk_copies = TransformBufferImageCopies(copies, map.offset, aspect_mask);
     scheduler->RequestOutsideRenderPassOperationContext();
-    scheduler->Record([buffer = map.buffer, image = *image, aspect_mask = aspect_mask,
+    scheduler->Record([buffer = map.buffer, image = *original_image, aspect_mask = aspect_mask,
                        vk_copies](vk::CommandBuffer cmdbuf) {
         const VkImageMemoryBarrier read_barrier{
             .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
@@ -1133,51 +1127,31 @@ void Image::DownloadMemory(const StagingBufferRef& map, std::span<const BufferIm
         cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
                                0, memory_write_barrier, nullptr, image_write_barrier);
     });
-    if (is_rescaled) {
-        SwapBackup();
-    }
 }
 
-bool Image::ScaleUp(bool save_as_backup) {
+bool Image::ScaleUp() {
     if (True(flags & ImageFlagBits::Rescaled)) {
         return false;
     }
     ASSERT(info.type != ImageType::Linear);
-    scaling_count++;
     flags |= ImageFlagBits::Rescaled;
 
     const auto& resolution = runtime->resolution;
     if (!resolution.active) {
         return true;
     }
-    vk::Image rescaled_image =
-        has_backup ? std::move(backup_image)
-                   : MakeImage(runtime->device, info, resolution.up_scale, resolution.down_shift);
-    MemoryCommit new_commit = has_backup ? std::move(backup_commit)
-                                         : MemoryCommit(runtime->memory_allocator.Commit(
-                                               rescaled_image, MemoryUsage::DeviceLocal));
-    has_backup = false;
-
+    const auto& device = runtime->device;
+    if (!scaled_image) {
+        scaled_image = MakeImage(device, info, resolution.up_scale, resolution.down_shift);
+        auto& allocator = runtime->memory_allocator;
+        scaled_commit = MemoryCommit(allocator.Commit(scaled_image, MemoryUsage::DeviceLocal));
+    }
     if (aspect_mask == 0) {
         aspect_mask = ImageAspectMask(info.format);
     }
-    SCOPE_EXIT({
-        if (save_as_backup) {
-            backup_image = std::move(image);
-            backup_commit = std::move(commit);
-            has_backup = true;
-        } else {
-            runtime->prescaled_images.Push(std::move(image));
-            runtime->prescaled_commits.Push(std::move(commit));
-        }
-        image = std::move(rescaled_image);
-        commit = std::move(new_commit);
-    });
-
     const PixelFormat format = StorageFormat(info.format);
-    const auto format_info =
-        MaxwellToVK::SurfaceFormat(runtime->device, FormatType::Optimal, false, format);
-    const auto similar = runtime->device.GetSupportedFormat(
+    const auto format_info = MaxwellToVK::SurfaceFormat(device, FormatType::Optimal, false, format);
+    const auto similar = device.GetSupportedFormat(
         format_info.format, (VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT),
         FormatType::Optimal);
 
@@ -1187,55 +1161,18 @@ bool Image::ScaleUp(bool save_as_backup) {
     if (aspect_mask == 0) {
         aspect_mask = ImageAspectMask(info.format);
     }
-    BlitScale(*scheduler, *image, *rescaled_image, info, aspect_mask, resolution, true);
+    BlitScale(*scheduler, *original_image, *scaled_image, info, aspect_mask, resolution, true);
+    current_image = *scaled_image;
     return true;
 }
 
-void Image::SwapBackup() {
-    if (!runtime->resolution.active) {
-        return;
-    }
-    ASSERT(has_backup);
-    runtime->prescaled_images.Push(std::move(image));
-    runtime->prescaled_commits.Push(std::move(commit));
-    image = std::move(backup_image);
-    commit = std::move(backup_commit);
-    has_backup = false;
-}
-
-bool Image::ScaleDown(bool save_as_backup) {
+bool Image::ScaleDown() {
     if (False(flags & ImageFlagBits::Rescaled)) {
         return false;
     }
     ASSERT(info.type != ImageType::Linear);
     flags &= ~ImageFlagBits::Rescaled;
-    scaling_count++;
-
-    const auto& resolution = runtime->resolution;
-    if (!resolution.active) {
-        return true;
-    }
-    vk::Image downscaled_image =
-        has_backup ? std::move(backup_image) : MakeImage(runtime->device, info);
-    MemoryCommit new_commit = has_backup ? std::move(backup_commit)
-                                         : MemoryCommit(runtime->memory_allocator.Commit(
-                                               downscaled_image, MemoryUsage::DeviceLocal));
-    has_backup = false;
-    if (aspect_mask == 0) {
-        aspect_mask = ImageAspectMask(info.format);
-    }
-    BlitScale(*scheduler, *image, *downscaled_image, info, aspect_mask, resolution, false);
-
-    if (save_as_backup) {
-        backup_image = std::move(image);
-        backup_commit = std::move(commit);
-        has_backup = true;
-    } else {
-        runtime->prescaled_images.Push(std::move(image));
-        runtime->prescaled_commits.Push(std::move(commit));
-    }
-    image = std::move(downscaled_image);
-    commit = std::move(new_commit);
+    current_image = *original_image;
     return true;
 }
 
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.h b/src/video_core/renderer_vulkan/vk_texture_cache.h
index 84194b833f..e5060e3f17 100644
--- a/src/video_core/renderer_vulkan/vk_texture_cache.h
+++ b/src/video_core/renderer_vulkan/vk_texture_cache.h
@@ -8,7 +8,6 @@
 
 #include "common/settings.h"
 #include "shader_recompiler/shader_info.h"
-#include "video_core/delayed_destruction_ring.h"
 #include "video_core/renderer_vulkan/vk_staging_buffer_pool.h"
 #include "video_core/texture_cache/image_view_base.h"
 #include "video_core/texture_cache/texture_cache_base.h"
@@ -17,7 +16,6 @@
 
 namespace Vulkan {
 
-using VideoCommon::DelayedDestructionRing;
 using VideoCommon::ImageId;
 using VideoCommon::NUM_RT;
 using VideoCommon::Region2D;
@@ -36,8 +34,6 @@ class VKScheduler;
 
 class TextureCacheRuntime {
 public:
-    static constexpr size_t TICKS_TO_DESTROY = 6;
-
     explicit TextureCacheRuntime(const Device& device_, VKScheduler& scheduler_,
                                  MemoryAllocator& memory_allocator_,
                                  StagingBufferPool& staging_buffer_pool_,
@@ -90,9 +86,6 @@ public:
     BlitImageHelper& blit_image_helper;
     ASTCDecoderPass& astc_decoder_pass;
     RenderPassCache& render_pass_cache;
-
-    DelayedDestructionRing<vk::Image, TICKS_TO_DESTROY> prescaled_images;
-    DelayedDestructionRing<MemoryCommit, TICKS_TO_DESTROY> prescaled_commits;
     Settings::ResolutionScalingInfo resolution;
 };
 
@@ -117,7 +110,7 @@ public:
                         std::span<const VideoCommon::BufferImageCopy> copies);
 
     [[nodiscard]] VkImage Handle() const noexcept {
-        return *image;
+        return current_image;
     }
 
     [[nodiscard]] VkImageAspectFlags AspectMask() const noexcept {
@@ -133,25 +126,22 @@ public:
         return std::exchange(initialized, true);
     }
 
-    bool ScaleUp(bool save_as_backup = false);
+    bool ScaleUp();
 
-    bool ScaleDown(bool save_as_backup = false);
-
-    void SwapBackup();
+    bool ScaleDown();
 
 private:
-    VKScheduler* scheduler;
-    vk::Image image;
+    VKScheduler* scheduler{};
+    TextureCacheRuntime* runtime{};
+
+    vk::Image original_image;
     MemoryCommit commit;
-    vk::ImageView image_view;
     std::vector<vk::ImageView> storage_image_views;
     VkImageAspectFlags aspect_mask = 0;
     bool initialized = false;
-    TextureCacheRuntime* runtime;
-    u32 scaling_count{};
-    vk::Image backup_image{};
-    MemoryCommit backup_commit{};
-    bool has_backup{};
+    vk::Image scaled_image{};
+    MemoryCommit scaled_commit{};
+    VkImage current_image{};
 };
 
 class ImageView : public VideoCommon::ImageViewBase {