mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-09-01 18:53:17 +00:00
Let's try this on memory reclamations
This commit is contained in:
@@ -129,6 +129,10 @@ public:
|
|||||||
return master_semaphore->IsFree(tick);
|
return master_semaphore->IsFree(tick);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RefreshTick() {
|
||||||
|
master_semaphore->Refresh();
|
||||||
|
}
|
||||||
|
|
||||||
/// Waits for the given GPU tick, optionally pacing frames.
|
/// Waits for the given GPU tick, optionally pacing frames.
|
||||||
void Wait(u64 tick, double target_fps = 0.0) {
|
void Wait(u64 tick, double target_fps = 0.0) {
|
||||||
if (tick > 0) {
|
if (tick > 0) {
|
||||||
|
|||||||
@@ -3235,6 +3235,14 @@ u64 TextureCacheRuntime::CurrentTick() const noexcept {
|
|||||||
return scheduler.CurrentTick();
|
return scheduler.CurrentTick();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool TextureCacheRuntime::IsDirectUploadRetired(u64 tick) {
|
||||||
|
if (scheduler.IsFree(tick)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
scheduler.RefreshTick();
|
||||||
|
return scheduler.IsFree(tick);
|
||||||
|
}
|
||||||
|
|
||||||
void TextureCacheRuntime::TransitionImageLayout(Image& image) {
|
void TextureCacheRuntime::TransitionImageLayout(Image& image) {
|
||||||
if (!image.ExchangeInitialization()) {
|
if (!image.ExchangeInitialization()) {
|
||||||
VkImageMemoryBarrier barrier{
|
VkImageMemoryBarrier barrier{
|
||||||
|
|||||||
@@ -116,6 +116,8 @@ public:
|
|||||||
|
|
||||||
[[nodiscard]] u64 CurrentTick() const noexcept;
|
[[nodiscard]] u64 CurrentTick() const noexcept;
|
||||||
|
|
||||||
|
[[nodiscard]] bool IsDirectUploadRetired(u64 tick);
|
||||||
|
|
||||||
void InsertUploadMemoryBarrier() {}
|
void InsertUploadMemoryBarrier() {}
|
||||||
|
|
||||||
void TransitionImageLayout(Image& image);
|
void TransitionImageLayout(Image& image);
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ struct ImageBase {
|
|||||||
u32 scale_rating = 0;
|
u32 scale_rating = 0;
|
||||||
u64 scale_tick = 0;
|
u64 scale_tick = 0;
|
||||||
bool has_scaled = false;
|
bool has_scaled = false;
|
||||||
bool direct_upload_used = false;
|
u64 direct_upload_tick = 0;
|
||||||
bool direct_upload_blocked = false;
|
bool direct_upload_blocked = false;
|
||||||
|
|
||||||
size_t channel = 0;
|
size_t channel = 0;
|
||||||
|
|||||||
@@ -119,13 +119,16 @@ void TextureCache<P>::RunGarbageCollector() {
|
|||||||
bool aggressive_mode = false;
|
bool aggressive_mode = false;
|
||||||
u64 ticks_to_destroy = 0;
|
u64 ticks_to_destroy = 0;
|
||||||
size_t num_iterations = 0;
|
size_t num_iterations = 0;
|
||||||
|
size_t num_downloads = 0;
|
||||||
const auto Configure = [&](bool allow_aggressive) {
|
const auto Configure = [&](bool allow_aggressive) {
|
||||||
high_priority_mode = total_used_memory >= expected_memory;
|
high_priority_mode = total_used_memory >= expected_memory;
|
||||||
aggressive_mode = allow_aggressive && total_used_memory >= critical_memory;
|
aggressive_mode = allow_aggressive && total_used_memory >= critical_memory;
|
||||||
ticks_to_destroy = aggressive_mode ? 10ULL : high_priority_mode ? 25ULL : 50ULL;
|
ticks_to_destroy = aggressive_mode ? 10ULL : high_priority_mode ? 25ULL : 50ULL;
|
||||||
num_iterations = aggressive_mode ? 40 : (high_priority_mode ? 20 : 10);
|
num_iterations = aggressive_mode ? 40 : (high_priority_mode ? 20 : 10);
|
||||||
|
num_downloads = MAX_GC_DOWNLOADS_PER_PASS;
|
||||||
};
|
};
|
||||||
const auto Cleanup = [this, &num_iterations, &high_priority_mode, &aggressive_mode](ImageId image_id) {
|
const auto Cleanup = [this, &num_iterations, &num_downloads, &high_priority_mode,
|
||||||
|
&aggressive_mode](ImageId image_id) {
|
||||||
if (num_iterations == 0) {
|
if (num_iterations == 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -139,6 +142,10 @@ void TextureCache<P>::RunGarbageCollector() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (must_download) {
|
if (must_download) {
|
||||||
|
if (num_downloads == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
--num_downloads;
|
||||||
auto map = runtime.DownloadStagingBuffer(image.unswizzled_size_bytes);
|
auto map = runtime.DownloadStagingBuffer(image.unswizzled_size_bytes);
|
||||||
const auto copies = FixSmallVectorADL(FullDownloadCopies(image.info));
|
const auto copies = FixSmallVectorADL(FullDownloadCopies(image.info));
|
||||||
image.DownloadMemory(map, copies);
|
image.DownloadMemory(map, copies);
|
||||||
@@ -585,9 +592,14 @@ FramebufferId TextureCache<P>::GetFramebufferId(const RenderTargets& key) {
|
|||||||
template <class P>
|
template <class P>
|
||||||
void TextureCache<P>::WriteMemory(DAddr cpu_addr, size_t size) {
|
void TextureCache<P>::WriteMemory(DAddr cpu_addr, size_t size) {
|
||||||
ForEachImageInRegion(cpu_addr, size, [this](ImageId image_id, Image& image) {
|
ForEachImageInRegion(cpu_addr, size, [this](ImageId image_id, Image& image) {
|
||||||
if (image.direct_upload_used) {
|
if constexpr (USE_UNIFIED_MEMORY) {
|
||||||
image.direct_upload_used = false;
|
if (image.direct_upload_tick != 0) {
|
||||||
image.direct_upload_blocked = true;
|
const u64 upload_tick = image.direct_upload_tick;
|
||||||
|
image.direct_upload_tick = 0;
|
||||||
|
if (!runtime.IsDirectUploadRetired(upload_tick)) {
|
||||||
|
image.direct_upload_blocked = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (True(image.flags & ImageFlagBits::CpuModified)) {
|
if (True(image.flags & ImageFlagBits::CpuModified)) {
|
||||||
return;
|
return;
|
||||||
@@ -1195,7 +1207,7 @@ bool TextureCache<P>::TryUploadFromUnifiedMemory([[maybe_unused]] Image& image)
|
|||||||
local_offset, FixSmallVectorADL(swizzles))) {
|
local_offset, FixSmallVectorADL(swizzles))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
image.direct_upload_used = true;
|
image.direct_upload_tick = runtime.CurrentTick();
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -121,6 +121,7 @@ class TextureCache : public VideoCommon::ChannelSetupCaches<TextureCacheChannelI
|
|||||||
static constexpr s64 DEFAULT_EXPECTED_MEMORY = 1_GiB + 125_MiB;
|
static constexpr s64 DEFAULT_EXPECTED_MEMORY = 1_GiB + 125_MiB;
|
||||||
static constexpr s64 DEFAULT_CRITICAL_MEMORY = 1_GiB + 625_MiB;
|
static constexpr s64 DEFAULT_CRITICAL_MEMORY = 1_GiB + 625_MiB;
|
||||||
static constexpr size_t GC_EMERGENCY_COUNTS = 2;
|
static constexpr size_t GC_EMERGENCY_COUNTS = 2;
|
||||||
|
static constexpr size_t MAX_GC_DOWNLOADS_PER_PASS = 4;
|
||||||
|
|
||||||
using Runtime = typename P::Runtime;
|
using Runtime = typename P::Runtime;
|
||||||
using Image = typename P::Image;
|
using Image = typename P::Image;
|
||||||
|
|||||||
@@ -1525,7 +1525,11 @@ u64 Device::GetDeviceMemoryUsage() const {
|
|||||||
for (const size_t heap : valid_heap_memory) {
|
for (const size_t heap : valid_heap_memory) {
|
||||||
result += budget.heapUsage[heap];
|
result += budget.heapUsage[heap];
|
||||||
}
|
}
|
||||||
return result;
|
const u64 committed_backing = Common::GetCommittedBackingSize();
|
||||||
|
if (result <= committed_backing) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return result - committed_backing;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Device::CollectPhysicalMemoryInfo() {
|
void Device::CollectPhysicalMemoryInfo() {
|
||||||
|
|||||||
Reference in New Issue
Block a user