Răsfoiți Sursa

Texture Cache: Release stagging buffers on tick frame

Fernando Sahmkow 3 ani în urmă
părinte
comite
4bc5469f52

+ 12 - 7
src/video_core/renderer_opengl/gl_texture_cache.cpp

@@ -801,14 +801,22 @@ void Image::UploadMemory(const ImageBufferMap& map,
     UploadMemory(map.buffer, map.offset, copies);
 }
 
-void Image::DownloadMemory(std::span<GLuint> buffer_handles, size_t buffer_offset,
+void Image::DownloadMemory(GLuint buffer_handle, size_t buffer_offset,
+                           std::span<const VideoCommon::BufferImageCopy> copies) {
+    std::array buffer_handles{buffer_handle};
+    std::array buffer_offsets{buffer_offset};
+    DownloadMemory(buffer_handles, buffer_offsets, copies);
+}
+
+void Image::DownloadMemory(std::span<GLuint> buffer_handles, std::span<size_t> buffer_offsets,
                            std::span<const VideoCommon::BufferImageCopy> copies) {
     const bool is_rescaled = True(flags & ImageFlagBits::Rescaled);
     if (is_rescaled) {
         ScaleDown();
     }
     glMemoryBarrier(GL_PIXEL_BUFFER_BARRIER_BIT); // TODO: Move this to its own API
-    for (auto buffer_handle : buffer_handles) {
+    for (size_t i = 0; i < buffer_handles.size(); i++) {
+        auto& buffer_handle = buffer_handles[i];
         glBindBuffer(GL_PIXEL_PACK_BUFFER, buffer_handle);
         glPixelStorei(GL_PACK_ALIGNMENT, 1);
 
@@ -827,7 +835,7 @@ void Image::DownloadMemory(std::span<GLuint> buffer_handles, size_t buffer_offse
                 current_image_height = copy.buffer_image_height;
                 glPixelStorei(GL_PACK_IMAGE_HEIGHT, current_image_height);
             }
-            CopyImageToBuffer(copy, buffer_offset);
+            CopyImageToBuffer(copy, buffer_offsets[i]);
         }
     }
     if (is_rescaled) {
@@ -837,10 +845,7 @@ void Image::DownloadMemory(std::span<GLuint> buffer_handles, size_t buffer_offse
 
 void Image::DownloadMemory(ImageBufferMap& map,
                            std::span<const VideoCommon::BufferImageCopy> copies) {
-    std::array buffers{
-        map.buffer,
-    };
-    DownloadMemory(buffers, map.offset, copies);
+    DownloadMemory(map.buffer, map.offset, copies);
 }
 
 GLuint Image::StorageHandle() noexcept {

+ 4 - 1
src/video_core/renderer_opengl/gl_texture_cache.h

@@ -212,7 +212,10 @@ public:
     void UploadMemory(const ImageBufferMap& map,
                       std::span<const VideoCommon::BufferImageCopy> copies);
 
-    void DownloadMemory(std::span<GLuint> buffer_handle, size_t buffer_offset,
+    void DownloadMemory(GLuint buffer_handle, size_t buffer_offset,
+                        std::span<const VideoCommon::BufferImageCopy> copies);
+
+    void DownloadMemory(std::span<GLuint> buffer_handle, std::span<size_t> buffer_offset,
                         std::span<const VideoCommon::BufferImageCopy> copies);
 
     void DownloadMemory(ImageBufferMap& map, std::span<const VideoCommon::BufferImageCopy> copies);

+ 12 - 1
src/video_core/renderer_vulkan/vk_texture_cache.cpp

@@ -1,4 +1,4 @@
-// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
+// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
 // SPDX-License-Identifier: GPL-3.0-or-later
 
 #include <algorithm>
@@ -1342,6 +1342,17 @@ void Image::UploadMemory(const StagingBufferRef& map, std::span<const BufferImag
     UploadMemory(map.buffer, map.offset, copies);
 }
 
+void Image::DownloadMemory(VkBuffer buffer, VkDeviceSize offset,
+                           std::span<const VideoCommon::BufferImageCopy> copies) {
+    std::array buffer_handles{
+        buffer,
+    };
+    std::array buffer_offsets{
+        offset,
+    };
+    DownloadMemory(buffer_handles, buffer_offsets, copies);
+}
+
 void Image::DownloadMemory(std::span<VkBuffer> buffers_span, std::span<VkDeviceSize> offsets_span,
                            std::span<const VideoCommon::BufferImageCopy> copies) {
     const bool is_rescaled = True(flags & ImageFlagBits::Rescaled);

+ 4 - 1
src/video_core/renderer_vulkan/vk_texture_cache.h

@@ -1,4 +1,4 @@
-// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
+// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
 // SPDX-License-Identifier: GPL-3.0-or-later
 
 #pragma once
@@ -138,6 +138,9 @@ public:
     void UploadMemory(const StagingBufferRef& map,
                       std::span<const VideoCommon::BufferImageCopy> copies);
 
+    void DownloadMemory(VkBuffer buffer, VkDeviceSize offset,
+                        std::span<const VideoCommon::BufferImageCopy> copies);
+
     void DownloadMemory(std::span<VkBuffer> buffers, std::span<VkDeviceSize> offsets,
                         std::span<const VideoCommon::BufferImageCopy> copies);
 

+ 13 - 9
src/video_core/texture_cache/texture_cache.h

@@ -139,6 +139,13 @@ void TextureCache<P>::TickFrame() {
     runtime.TickFrame();
     critical_gc = 0;
     ++frame_tick;
+
+    if constexpr (IMPLEMENTS_ASYNC_DOWNLOADS) {
+        for (auto& buffer : async_buffers_death_ring) {
+            runtime.FreeDeferredStagingBuffer(buffer);
+        }
+        async_buffers_death_ring.clear();
+    }
 }
 
 template <class P>
@@ -688,10 +695,10 @@ void TextureCache<P>::CommitAsyncFlushes() {
             }
             uncommitted_async_buffers.emplace_back(download_map);
         }
+        async_buffers.emplace_back(std::move(uncommitted_async_buffers));
+        uncommitted_async_buffers.clear();
     }
     committed_downloads.emplace_back(std::move(uncommitted_downloads));
-    async_buffers.emplace_back(std::move(uncommitted_async_buffers));
-    uncommitted_async_buffers.clear();
     uncommitted_downloads.clear();
 }
 
@@ -729,7 +736,7 @@ void TextureCache<P>::PopAsyncFlushes() {
             }
         }
         for (auto& download_buffer : download_map) {
-            runtime.FreeDeferredStagingBuffer(download_buffer);
+            async_buffers_death_ring.emplace_back(download_buffer);
         }
         committed_downloads.pop_front();
         async_buffers.pop_front();
@@ -748,7 +755,7 @@ void TextureCache<P>::PopAsyncFlushes() {
         auto download_map = runtime.DownloadStagingBuffer(total_size_bytes);
         const size_t original_offset = download_map.offset;
         for (const PendingDownload& download_info : download_ids) {
-            if (download_info.is_swizzle) {
+            if (!download_info.is_swizzle) {
                 continue;
             }
             Image& image = slot_images[download_info.object_id];
@@ -761,7 +768,7 @@ void TextureCache<P>::PopAsyncFlushes() {
         download_map.offset = original_offset;
         std::span<u8> download_span = download_map.mapped_span;
         for (const PendingDownload& download_info : download_ids) {
-            if (download_info.is_swizzle) {
+            if (!download_info.is_swizzle) {
                 continue;
             }
             const ImageBase& image = slot_images[download_info.object_id];
@@ -887,10 +894,7 @@ void TextureCache<P>::DownloadImageIntoBuffer(typename TextureCache<P>::Image* i
         };
         image->DownloadMemory(buffers, buffer_offsets, copies);
     } else {
-        std::array buffers{
-            buffer,
-        };
-        image->DownloadMemory(buffers, buffer_offset, copies);
+        image->DownloadMemory(buffer, buffer_offset, copies);
     }
 }
 

+ 1 - 0
src/video_core/texture_cache/texture_cache_base.h

@@ -449,6 +449,7 @@ private:
     std::deque<std::vector<PendingDownload>> committed_downloads;
     std::vector<AsyncBuffer> uncommitted_async_buffers;
     std::deque<std::vector<AsyncBuffer>> async_buffers;
+    std::deque<AsyncBuffer> async_buffers_death_ring;
 
     struct LRUItemParams {
         using ObjectType = ImageId;