mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-27 16:02:37 +00:00
graphics: drop image heap table snapshots superseded at the same base
This commit is contained in:
1 parent
ba7f9969ef
commit
c1dfb309a1
4 files changed
+50
-14
No files matched your search
@@ -526,26 +526,46 @@ void ImageHeap::UnmapMemory(uint64_t address, uint64_t size) {
|
|||||||
} else {
|
} else {
|
||||||
m_unmapped.push_back({address, size});
|
m_unmapped.push_back({address, size});
|
||||||
}
|
}
|
||||||
auto& scheduler = m_context.GetCommandScheduler();
|
|
||||||
std::scoped_lock lock {m_mutex};
|
std::scoped_lock lock {m_mutex};
|
||||||
std::erase_if(m_memories, [&](const std::unique_ptr<Memory>& memory) {
|
std::erase_if(m_memories, [&](const std::unique_ptr<Memory>& memory) {
|
||||||
if (address >= memory->base + memory->size || memory->base >= address + size) {
|
if (address >= memory->base + memory->size || memory->base >= address + size) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Unwatch(*memory);
|
Drop(*memory);
|
||||||
for (auto& view: memory->views) {
|
|
||||||
std::erase(m_active, view.get());
|
|
||||||
for (const auto& [value, index]: view->elements) {
|
|
||||||
Unreference(m_elements[index]);
|
|
||||||
view->released.push_back(index);
|
|
||||||
}
|
|
||||||
Retire(*view);
|
|
||||||
if (scheduler.Active()) {
|
|
||||||
scheduler.DeferOperation([buffer = std::move(view->buffer)] {});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ImageHeap::RunGarbageCollector() {
|
||||||
|
// A table whose descriptor grew keeps its old snapshot until a frame passes without it.
|
||||||
|
std::scoped_lock lock {m_mutex};
|
||||||
|
std::vector<uint64_t> acquired;
|
||||||
|
for (const auto& memory: m_memories) {
|
||||||
|
if (memory->draw > m_frame_draw) acquired.push_back(memory->base);
|
||||||
|
}
|
||||||
|
std::erase_if(m_memories, [&](const std::unique_ptr<Memory>& memory) {
|
||||||
|
const bool superseded = memory->draw <= m_frame_draw &&
|
||||||
|
std::ranges::find(acquired, memory->base) != acquired.end();
|
||||||
|
if (superseded) Drop(*memory);
|
||||||
|
return superseded;
|
||||||
|
});
|
||||||
|
m_frame_draw = m_draw;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImageHeap::Drop(Memory& memory) {
|
||||||
|
auto& scheduler = m_context.GetCommandScheduler();
|
||||||
|
Unwatch(memory);
|
||||||
|
for (auto& view: memory.views) {
|
||||||
|
std::erase(m_active, view.get());
|
||||||
|
for (const auto& [value, index]: view->elements) {
|
||||||
|
Unreference(m_elements[index]);
|
||||||
|
view->released.push_back(index);
|
||||||
|
}
|
||||||
|
Retire(*view);
|
||||||
|
if (scheduler.Active()) {
|
||||||
|
scheduler.DeferOperation([buffer = std::move(view->buffer)] {});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Libs::Graphics
|
} // namespace Libs::Graphics
|
||||||
@@ -46,6 +46,8 @@ public:
|
|||||||
// CPU write fault, on any thread.
|
// CPU write fault, on any thread.
|
||||||
void InvalidateMemory(uint64_t address, uint64_t size);
|
void InvalidateMemory(uint64_t address, uint64_t size);
|
||||||
void UnmapMemory(uint64_t address, uint64_t size);
|
void UnmapMemory(uint64_t address, uint64_t size);
|
||||||
|
// Frame boundary: drops table snapshots that another at the same base replaced this frame.
|
||||||
|
void RunGarbageCollector();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
using DescriptorValue = ShaderRecompiler::IR::DescriptorValue;
|
using DescriptorValue = ShaderRecompiler::IR::DescriptorValue;
|
||||||
@@ -113,6 +115,7 @@ private:
|
|||||||
Image* ImageOf(const Element& element) const;
|
Image* ImageOf(const Element& element) const;
|
||||||
uint32_t Allocate();
|
uint32_t Allocate();
|
||||||
void Retire(View& view);
|
void Retire(View& view);
|
||||||
|
void Drop(Memory& memory);
|
||||||
void WriteDescriptors();
|
void WriteDescriptors();
|
||||||
|
|
||||||
RenderContext& m_context;
|
RenderContext& m_context;
|
||||||
@@ -120,7 +123,8 @@ private:
|
|||||||
std::mutex m_mutex; // Fault-visible Memory state and m_memories.
|
std::mutex m_mutex; // Fault-visible Memory state and m_memories.
|
||||||
std::vector<std::unique_ptr<Memory>> m_memories;
|
std::vector<std::unique_ptr<Memory>> m_memories;
|
||||||
std::vector<View*> m_active; // Acquired since the last commit.
|
std::vector<View*> m_active; // Acquired since the last commit.
|
||||||
uint64_t m_draw = 1;
|
uint64_t m_draw = 1;
|
||||||
|
uint64_t m_frame_draw = 0; // Last draw before this frame.
|
||||||
std::vector<Element> m_elements;
|
std::vector<Element> m_elements;
|
||||||
std::vector<uint32_t> m_free;
|
std::vector<uint32_t> m_free;
|
||||||
std::deque<std::pair<uint64_t, uint32_t>> m_retired; // Tick, element.
|
std::deque<std::pair<uint64_t, uint32_t>> m_retired; // Tick, element.
|
||||||
|
|||||||
@@ -148,6 +148,7 @@ void RenderContext::RunGarbageCollector() {
|
|||||||
m_buffer_cache.ProcessFaultBuffer();
|
m_buffer_cache.ProcessFaultBuffer();
|
||||||
}
|
}
|
||||||
m_texture_cache.ProcessDownloadImages();
|
m_texture_cache.ProcessDownloadImages();
|
||||||
|
m_image_heap.RunGarbageCollector();
|
||||||
m_texture_cache.RunGarbageCollector();
|
m_texture_cache.RunGarbageCollector();
|
||||||
m_buffer_cache.RunGarbageCollector();
|
m_buffer_cache.RunGarbageCollector();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5511,6 +5511,17 @@ public:
|
|||||||
ImageHeapTestAccess::ImageOf(heap, filtered.slots[240]),
|
ImageHeapTestAccess::ImageOf(heap, filtered.slots[240]),
|
||||||
"a reactivated view kept an element whose image slot holds a new image");
|
"a reactivated view kept an element whose image slot holds a new image");
|
||||||
|
|
||||||
|
// A table whose descriptor grew keeps its old snapshot until a frame passes without it.
|
||||||
|
const IR::ImageHeapRequest grown{table, table_size * 2u, 32u, 0u, table_size / 16u, &sampled};
|
||||||
|
for (uint32_t frame = 0; frame < 2u; ++frame) {
|
||||||
|
Require(name, "grown table", heap.Acquire(grown, view), "a grown table was declined");
|
||||||
|
draw();
|
||||||
|
heap.RunGarbageCollector();
|
||||||
|
heap.BeginDraw();
|
||||||
|
Require(name, "superseded table", ImageHeapTestAccess::MemoryCount(heap) == 2u - frame,
|
||||||
|
"a snapshot was dropped in a frame that acquired it or kept after one without it");
|
||||||
|
}
|
||||||
|
|
||||||
heap.UnmapMemory(table, table_size);
|
heap.UnmapMemory(table, table_size);
|
||||||
Require(name, "unmapped table",
|
Require(name, "unmapped table",
|
||||||
ImageHeapTestAccess::MemoryCount(heap) == 0u &&
|
ImageHeapTestAccess::MemoryCount(heap) == 0u &&
|
||||||
|
|||||||
Reference in new issue
Block a user