mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-28 22:06:59 +01:00
fix(renderer): resolve delayed GPU page faults through buffer and texture caches
This commit is contained in:
+2
-1
@@ -394,6 +394,7 @@ void BufferCache::InvalidateMemory(uint64_t vaddr, uint64_t size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void BufferCache::ReadMemory(uint64_t vaddr, uint64_t size) {
|
void BufferCache::ReadMemory(uint64_t vaddr, uint64_t size) {
|
||||||
|
(void)SynchronizeBacking(vaddr, size);
|
||||||
std::vector<DownloadCopy> copies;
|
std::vector<DownloadCopy> copies;
|
||||||
{
|
{
|
||||||
FaultSafeCacheLock lock(this, m_mutex);
|
FaultSafeCacheLock lock(this, m_mutex);
|
||||||
@@ -426,7 +427,7 @@ void BufferCache::ReadMemory(uint64_t vaddr, uint64_t size) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (copies.empty()) {
|
if (copies.empty()) {
|
||||||
EXIT("BufferCache: GPU-owned invalidation has no dirty byte ranges\n");
|
return;
|
||||||
}
|
}
|
||||||
auto downloads = RecordDownloads(copies);
|
auto downloads = RecordDownloads(copies);
|
||||||
m_scheduler.FinishCurrent();
|
m_scheduler.FinishCurrent();
|
||||||
|
|||||||
+1
-1
@@ -50,6 +50,7 @@ public:
|
|||||||
[[nodiscard]] bool InvalidateMemory(PageFaultAccess access, uint64_t vaddr, uint64_t size,
|
[[nodiscard]] bool InvalidateMemory(PageFaultAccess access, uint64_t vaddr, uint64_t size,
|
||||||
PageFaultPhase phase) noexcept;
|
PageFaultPhase phase) noexcept;
|
||||||
void InvalidateMemory(uint64_t vaddr, uint64_t size);
|
void InvalidateMemory(uint64_t vaddr, uint64_t size);
|
||||||
|
void ReadMemory(uint64_t vaddr, uint64_t size);
|
||||||
void UnmapMemory(uint64_t vaddr, uint64_t size);
|
void UnmapMemory(uint64_t vaddr, uint64_t size);
|
||||||
[[nodiscard]] BufferBinding ObtainBuffer(CommandBuffer& command, uint64_t vaddr, uint64_t size,
|
[[nodiscard]] BufferBinding ObtainBuffer(CommandBuffer& command, uint64_t vaddr, uint64_t size,
|
||||||
bool is_written = false, bool is_read = true,
|
bool is_written = false, bool is_read = true,
|
||||||
@@ -111,7 +112,6 @@ private:
|
|||||||
void QueueGarbageDownload(std::span<const DownloadCopy> copies, RetiredBuffer retire);
|
void QueueGarbageDownload(std::span<const DownloadCopy> copies, RetiredBuffer retire);
|
||||||
void RefreshInvalidatedRanges(CommandBuffer& command, CachedBuffer& cached, uint64_t vaddr,
|
void RefreshInvalidatedRanges(CommandBuffer& command, CachedBuffer& cached, uint64_t vaddr,
|
||||||
uint64_t size, bool upload);
|
uint64_t size, bool upload);
|
||||||
void ReadMemory(uint64_t vaddr, uint64_t size);
|
|
||||||
void DiscardGpuDirtyBytesLocked(uint64_t vaddr, uint64_t size, const char* operation);
|
void DiscardGpuDirtyBytesLocked(uint64_t vaddr, uint64_t size, const char* operation);
|
||||||
void WriteHostMemory(uint64_t vaddr, std::span<const uint8_t> data);
|
void WriteHostMemory(uint64_t vaddr, std::span<const uint8_t> data);
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,8 @@ bool GpuResourceManager::InvalidateMemory(PageFaultAccess access, uint64_t vaddr
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool GpuResourceManager::HandleFault(PageFaultAccess access, uint64_t fault_vaddr) noexcept {
|
bool GpuResourceManager::HandleFault(PageFaultAccess access, uint64_t fault_vaddr) noexcept {
|
||||||
if (!m_page_manager.IsMapped(fault_vaddr, 1)) {
|
constexpr uint64_t fault_size = 8;
|
||||||
|
if (!IsMapped(fault_vaddr, fault_size)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (CommandScheduler::InDeferredOperation()) {
|
if (CommandScheduler::InDeferredOperation()) {
|
||||||
@@ -47,10 +48,15 @@ bool GpuResourceManager::HandleFault(PageFaultAccess access, uint64_t fault_vadd
|
|||||||
bool handled = false;
|
bool handled = false;
|
||||||
const auto resolve = [this, access, fault_vaddr, &handled](CommandProcessor& cp) {
|
const auto resolve = [this, access, fault_vaddr, &handled](CommandProcessor& cp) {
|
||||||
cp.BeginReadbackTransaction();
|
cp.BeginReadbackTransaction();
|
||||||
(void)m_buffer_cache.SynchronizeBacking(fault_vaddr, 1);
|
|
||||||
{
|
{
|
||||||
ResourceMutex::FaultScope fault(m_resource_mutex);
|
ResourceMutex::FaultScope fault(m_resource_mutex);
|
||||||
handled = m_page_manager.HandleFault(access, fault_vaddr);
|
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);
|
||||||
|
}
|
||||||
|
handled = true;
|
||||||
}
|
}
|
||||||
cp.EndReadbackTransaction();
|
cp.EndReadbackTransaction();
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user