Texture Cache: Release stagging buffers on tick frame
This commit is contained in:
parent
58d1c7c77a
commit
4bc5469f52
6 changed files with 46 additions and 19 deletions
|
@ -801,14 +801,22 @@ void Image::UploadMemory(const ImageBufferMap& map,
|
||||||
UploadMemory(map.buffer, map.offset, copies);
|
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) {
|
std::span<const VideoCommon::BufferImageCopy> copies) {
|
||||||
const bool is_rescaled = True(flags & ImageFlagBits::Rescaled);
|
const bool is_rescaled = True(flags & ImageFlagBits::Rescaled);
|
||||||
if (is_rescaled) {
|
if (is_rescaled) {
|
||||||
ScaleDown();
|
ScaleDown();
|
||||||
}
|
}
|
||||||
glMemoryBarrier(GL_PIXEL_BUFFER_BARRIER_BIT); // TODO: Move this to its own API
|
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);
|
glBindBuffer(GL_PIXEL_PACK_BUFFER, buffer_handle);
|
||||||
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
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;
|
current_image_height = copy.buffer_image_height;
|
||||||
glPixelStorei(GL_PACK_IMAGE_HEIGHT, current_image_height);
|
glPixelStorei(GL_PACK_IMAGE_HEIGHT, current_image_height);
|
||||||
}
|
}
|
||||||
CopyImageToBuffer(copy, buffer_offset);
|
CopyImageToBuffer(copy, buffer_offsets[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (is_rescaled) {
|
if (is_rescaled) {
|
||||||
|
@ -837,10 +845,7 @@ void Image::DownloadMemory(std::span<GLuint> buffer_handles, size_t buffer_offse
|
||||||
|
|
||||||
void Image::DownloadMemory(ImageBufferMap& map,
|
void Image::DownloadMemory(ImageBufferMap& map,
|
||||||
std::span<const VideoCommon::BufferImageCopy> copies) {
|
std::span<const VideoCommon::BufferImageCopy> copies) {
|
||||||
std::array buffers{
|
DownloadMemory(map.buffer, map.offset, copies);
|
||||||
map.buffer,
|
|
||||||
};
|
|
||||||
DownloadMemory(buffers, map.offset, copies);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GLuint Image::StorageHandle() noexcept {
|
GLuint Image::StorageHandle() noexcept {
|
||||||
|
|
|
@ -212,7 +212,10 @@ public:
|
||||||
void UploadMemory(const ImageBufferMap& map,
|
void UploadMemory(const ImageBufferMap& map,
|
||||||
std::span<const VideoCommon::BufferImageCopy> copies);
|
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);
|
std::span<const VideoCommon::BufferImageCopy> copies);
|
||||||
|
|
||||||
void DownloadMemory(ImageBufferMap& map, std::span<const VideoCommon::BufferImageCopy> copies);
|
void DownloadMemory(ImageBufferMap& map, std::span<const VideoCommon::BufferImageCopy> copies);
|
||||||
|
|
|
@ -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
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
@ -1342,6 +1342,17 @@ void Image::UploadMemory(const StagingBufferRef& map, std::span<const BufferImag
|
||||||
UploadMemory(map.buffer, map.offset, copies);
|
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,
|
void Image::DownloadMemory(std::span<VkBuffer> buffers_span, std::span<VkDeviceSize> offsets_span,
|
||||||
std::span<const VideoCommon::BufferImageCopy> copies) {
|
std::span<const VideoCommon::BufferImageCopy> copies) {
|
||||||
const bool is_rescaled = True(flags & ImageFlagBits::Rescaled);
|
const bool is_rescaled = True(flags & ImageFlagBits::Rescaled);
|
||||||
|
|
|
@ -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
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
@ -138,6 +138,9 @@ public:
|
||||||
void UploadMemory(const StagingBufferRef& map,
|
void UploadMemory(const StagingBufferRef& map,
|
||||||
std::span<const VideoCommon::BufferImageCopy> copies);
|
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,
|
void DownloadMemory(std::span<VkBuffer> buffers, std::span<VkDeviceSize> offsets,
|
||||||
std::span<const VideoCommon::BufferImageCopy> copies);
|
std::span<const VideoCommon::BufferImageCopy> copies);
|
||||||
|
|
||||||
|
|
|
@ -139,6 +139,13 @@ void TextureCache<P>::TickFrame() {
|
||||||
runtime.TickFrame();
|
runtime.TickFrame();
|
||||||
critical_gc = 0;
|
critical_gc = 0;
|
||||||
++frame_tick;
|
++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>
|
template <class P>
|
||||||
|
@ -688,10 +695,10 @@ void TextureCache<P>::CommitAsyncFlushes() {
|
||||||
}
|
}
|
||||||
uncommitted_async_buffers.emplace_back(download_map);
|
uncommitted_async_buffers.emplace_back(download_map);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
committed_downloads.emplace_back(std::move(uncommitted_downloads));
|
|
||||||
async_buffers.emplace_back(std::move(uncommitted_async_buffers));
|
async_buffers.emplace_back(std::move(uncommitted_async_buffers));
|
||||||
uncommitted_async_buffers.clear();
|
uncommitted_async_buffers.clear();
|
||||||
|
}
|
||||||
|
committed_downloads.emplace_back(std::move(uncommitted_downloads));
|
||||||
uncommitted_downloads.clear();
|
uncommitted_downloads.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -729,7 +736,7 @@ void TextureCache<P>::PopAsyncFlushes() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (auto& download_buffer : download_map) {
|
for (auto& download_buffer : download_map) {
|
||||||
runtime.FreeDeferredStagingBuffer(download_buffer);
|
async_buffers_death_ring.emplace_back(download_buffer);
|
||||||
}
|
}
|
||||||
committed_downloads.pop_front();
|
committed_downloads.pop_front();
|
||||||
async_buffers.pop_front();
|
async_buffers.pop_front();
|
||||||
|
@ -748,7 +755,7 @@ void TextureCache<P>::PopAsyncFlushes() {
|
||||||
auto download_map = runtime.DownloadStagingBuffer(total_size_bytes);
|
auto download_map = runtime.DownloadStagingBuffer(total_size_bytes);
|
||||||
const size_t original_offset = download_map.offset;
|
const size_t original_offset = download_map.offset;
|
||||||
for (const PendingDownload& download_info : download_ids) {
|
for (const PendingDownload& download_info : download_ids) {
|
||||||
if (download_info.is_swizzle) {
|
if (!download_info.is_swizzle) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Image& image = slot_images[download_info.object_id];
|
Image& image = slot_images[download_info.object_id];
|
||||||
|
@ -761,7 +768,7 @@ void TextureCache<P>::PopAsyncFlushes() {
|
||||||
download_map.offset = original_offset;
|
download_map.offset = original_offset;
|
||||||
std::span<u8> download_span = download_map.mapped_span;
|
std::span<u8> download_span = download_map.mapped_span;
|
||||||
for (const PendingDownload& download_info : download_ids) {
|
for (const PendingDownload& download_info : download_ids) {
|
||||||
if (download_info.is_swizzle) {
|
if (!download_info.is_swizzle) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const ImageBase& image = slot_images[download_info.object_id];
|
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);
|
image->DownloadMemory(buffers, buffer_offsets, copies);
|
||||||
} else {
|
} else {
|
||||||
std::array buffers{
|
image->DownloadMemory(buffer, buffer_offset, copies);
|
||||||
buffer,
|
|
||||||
};
|
|
||||||
image->DownloadMemory(buffers, buffer_offset, copies);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -449,6 +449,7 @@ private:
|
||||||
std::deque<std::vector<PendingDownload>> committed_downloads;
|
std::deque<std::vector<PendingDownload>> committed_downloads;
|
||||||
std::vector<AsyncBuffer> uncommitted_async_buffers;
|
std::vector<AsyncBuffer> uncommitted_async_buffers;
|
||||||
std::deque<std::vector<AsyncBuffer>> async_buffers;
|
std::deque<std::vector<AsyncBuffer>> async_buffers;
|
||||||
|
std::deque<AsyncBuffer> async_buffers_death_ring;
|
||||||
|
|
||||||
struct LRUItemParams {
|
struct LRUItemParams {
|
||||||
using ObjectType = ImageId;
|
using ObjectType = ImageId;
|
||||||
|
|
Loading…
Reference in a new issue