mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-20 02:47:02 +02:00
95 lines
2.9 KiB
C++
95 lines
2.9 KiB
C++
#include "graphics/host_gpu/renderer/cache/gpuResourceManager.h"
|
|
|
|
#include "common/assert.h"
|
|
#include "graphics/guest_gpu/graphicsRun.h"
|
|
#include "graphics/host_gpu/renderer/commandScheduler.h"
|
|
namespace Libs::Graphics {
|
|
|
|
GpuResourceManager::GpuResourceManager(GraphicContext& graphics, CommandScheduler& scheduler)
|
|
: m_scheduler(scheduler), m_buffer_cache(graphics, scheduler, m_page_manager, m_texture_cache),
|
|
m_texture_cache(graphics, scheduler, m_page_manager, m_buffer_cache) {}
|
|
|
|
GpuResourceManager::~GpuResourceManager() = default;
|
|
|
|
bool GpuResourceManager::HandleFault(PageFaultAccess access, uint64_t fault_vaddr) noexcept {
|
|
constexpr uint64_t fault_size = 8;
|
|
if (!IsMapped(fault_vaddr, fault_size)) {
|
|
return false;
|
|
}
|
|
if (access == PageFaultAccess::Write) {
|
|
m_buffer_cache.InvalidateMemory(fault_vaddr, fault_size);
|
|
m_texture_cache.InvalidateMemory(fault_vaddr, fault_size);
|
|
} else {
|
|
m_buffer_cache.ReadMemory(fault_vaddr, fault_size);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool GpuResourceManager::InvalidateMemory(uint64_t vaddr, uint64_t size) {
|
|
if (!IsMapped(vaddr, size)) {
|
|
return false;
|
|
}
|
|
m_buffer_cache.InvalidateMemory(vaddr, size);
|
|
m_texture_cache.InvalidateMemory(vaddr, size);
|
|
return true;
|
|
}
|
|
|
|
bool GpuResourceManager::IsMapped(uint64_t vaddr, uint64_t size) const noexcept {
|
|
if (!GuestRange {vaddr, size}.Valid()) {
|
|
return false;
|
|
}
|
|
std::shared_lock lock(m_mapped_ranges_mutex);
|
|
return m_mapped_ranges.Contains(vaddr, size);
|
|
}
|
|
|
|
void GpuResourceManager::MapMemory(uint64_t vaddr, uint64_t size) {
|
|
{
|
|
std::lock_guard lock(m_mapped_ranges_mutex);
|
|
m_mapped_ranges.Add(vaddr, size);
|
|
}
|
|
}
|
|
|
|
void GpuResourceManager::UnmapMemory(uint64_t vaddr, uint64_t size) {
|
|
if (CommandScheduler::InDeferredOperation()) {
|
|
EXIT("unsupported memory unmap from an asynchronous GPU completion, "
|
|
"addr=0x%016" PRIx64 " size=0x%016" PRIx64 "\n",
|
|
vaddr, size);
|
|
}
|
|
const auto unmap = [this, vaddr, size] {
|
|
if (m_scheduler.Active()) {
|
|
const auto tick = m_scheduler.CurrentTick();
|
|
m_scheduler.Finish();
|
|
m_scheduler.WaitPriorityOperations(tick);
|
|
}
|
|
m_buffer_cache.InvalidateMemory(vaddr, size);
|
|
m_texture_cache.UnmapMemory(vaddr, size);
|
|
std::lock_guard lock(m_mapped_ranges_mutex);
|
|
m_mapped_ranges.Subtract(vaddr, size);
|
|
};
|
|
if (m_gpu == nullptr) {
|
|
unmap();
|
|
return;
|
|
}
|
|
m_gpu->SendCommandSync(unmap);
|
|
}
|
|
|
|
void GpuResourceManager::PrepareBda() {
|
|
std::shared_lock lock(m_mapped_ranges_mutex);
|
|
m_mapped_ranges.ForEach([this](uint64_t start, uint64_t end) {
|
|
m_buffer_cache.SynchronizeBuffersInRange(start, end - start);
|
|
});
|
|
m_fault_process_pending = true;
|
|
}
|
|
|
|
void GpuResourceManager::RunGarbageCollector() {
|
|
if (m_fault_process_pending) {
|
|
m_fault_process_pending = false;
|
|
m_buffer_cache.ProcessFaultBuffer();
|
|
}
|
|
m_texture_cache.ProcessDownloadImages();
|
|
m_texture_cache.RunGarbageCollector();
|
|
m_buffer_cache.RunGarbageCollector();
|
|
}
|
|
|
|
} // namespace Libs::Graphics
|