mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-21 19:36:55 +02:00
graphics: bound the scratch a burst of detiles can hold
TileManager takes a device buffer per detile and returns it through DeferDestroy, which cannot run until the GPU retires the tick the free was queued at. A burst therefore holds every one of those buffers at once, and nothing bounded the total: measured at 409 MiB across 40 live buffers while an image allocation was failing 414 MiB short of the budget. Cap the outstanding scratch and drain the pending-operation queue before taking more. FlushAndWait alone is not enough - it waits for the GPU but does not pop the queue, so the frees have not run yet.
This commit is contained in:
@@ -1,3 +1,5 @@
|
|||||||
|
#include <atomic>
|
||||||
|
#include <cstdlib>
|
||||||
#include "graphics/host_gpu/renderer/image/tiler.h"
|
#include "graphics/host_gpu/renderer/image/tiler.h"
|
||||||
|
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
@@ -13,6 +15,7 @@
|
|||||||
#include "gpu_tiler_shaders/gpu_tiler_standard64_3d_spv.h"
|
#include "gpu_tiler_shaders/gpu_tiler_standard64_3d_spv.h"
|
||||||
#include "gpu_tiler_shaders/gpu_tiler_standard64_spv.h"
|
#include "gpu_tiler_shaders/gpu_tiler_standard64_spv.h"
|
||||||
#include "gpu_tiler_shaders/gpu_tiler_swap_bgra16_spv.h"
|
#include "gpu_tiler_shaders/gpu_tiler_swap_bgra16_spv.h"
|
||||||
|
#include "graphics/host_gpu/deferralBlock.h"
|
||||||
#include "graphics/host_gpu/graphicContext.h"
|
#include "graphics/host_gpu/graphicContext.h"
|
||||||
#include "graphics/host_gpu/renderer/cache/streamBuffer.h"
|
#include "graphics/host_gpu/renderer/cache/streamBuffer.h"
|
||||||
#include "graphics/host_gpu/renderer/commandScheduler.h"
|
#include "graphics/host_gpu/renderer/commandScheduler.h"
|
||||||
@@ -89,8 +92,19 @@ TileManager::~TileManager() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
std::atomic<uint64_t> g_scratch_live_bytes {0};
|
||||||
|
constexpr uint64_t SCRATCH_LIVE_BYTES_CAP = 192ull * 1024ull * 1024ull;
|
||||||
|
} // namespace
|
||||||
|
|
||||||
TileManager::Scratch TileManager::AllocateScratch(uint64_t size) {
|
TileManager::Scratch TileManager::AllocateScratch(uint64_t size) {
|
||||||
EXIT_IF(size == 0);
|
EXIT_IF(size == 0);
|
||||||
|
|
||||||
|
if (!CommandScheduler::InDeferredOperation() &&
|
||||||
|
g_scratch_live_bytes.load(std::memory_order_relaxed) + size > SCRATCH_LIVE_BYTES_CAP) {
|
||||||
|
m_scheduler.FlushAndWait();
|
||||||
|
m_scheduler.PopPendingOperations();
|
||||||
|
}
|
||||||
vk::BufferCreateInfo create {};
|
vk::BufferCreateInfo create {};
|
||||||
create.sType = vk::StructureType::eBufferCreateInfo;
|
create.sType = vk::StructureType::eBufferCreateInfo;
|
||||||
create.size = size;
|
create.size = size;
|
||||||
@@ -106,13 +120,16 @@ TileManager::Scratch TileManager::AllocateScratch(uint64_t size) {
|
|||||||
RequireVulkanSuccess(static_cast<vk::Result>(vmaCreateBuffer(
|
RequireVulkanSuccess(static_cast<vk::Result>(vmaCreateBuffer(
|
||||||
m_graphics.allocator, &raw, &allocate, &buffer, &memory, nullptr)),
|
m_graphics.allocator, &raw, &allocate, &buffer, &memory, nullptr)),
|
||||||
"allocate TileManager scratch buffer");
|
"allocate TileManager scratch buffer");
|
||||||
|
g_scratch_live_bytes.fetch_add(size, std::memory_order_relaxed);
|
||||||
return {buffer, memory, size};
|
return {buffer, memory, size};
|
||||||
}
|
}
|
||||||
|
|
||||||
void TileManager::DeferDestroy(Scratch scratch) {
|
void TileManager::DeferDestroy(Scratch scratch) {
|
||||||
auto allocator = m_graphics.allocator;
|
auto allocator = m_graphics.allocator;
|
||||||
m_scheduler.DeferOperation(
|
m_scheduler.DeferOperation([allocator, scratch] {
|
||||||
[allocator, scratch] { vmaDestroyBuffer(allocator, scratch.buffer, scratch.allocation); });
|
vmaDestroyBuffer(allocator, scratch.buffer, scratch.allocation);
|
||||||
|
g_scratch_live_bytes.fetch_sub(scratch.size, std::memory_order_relaxed);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void TileManager::Prepare(bool tile, uint64_t tiled_capacity, uint64_t linear_capacity,
|
void TileManager::Prepare(bool tile, uint64_t tiled_capacity, uint64_t linear_capacity,
|
||||||
|
|||||||
Reference in New Issue
Block a user