From 1f0d297221b8933955837eef8951feaedad16ebc Mon Sep 17 00:00:00 2001 From: Billy Laws Date: Wed, 15 Mar 2023 17:53:35 +0000 Subject: [PATCH] Fix infinite loop when reading dirty buffers with direct mem The code didn't account for interval Queries returning zero when reaching the end. --- app/src/main/cpp/skyline/gpu/buffer.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/app/src/main/cpp/skyline/gpu/buffer.cpp b/app/src/main/cpp/skyline/gpu/buffer.cpp index 5fb28b7d..f87614fa 100644 --- a/app/src/main/cpp/skyline/gpu/buffer.cpp +++ b/app/src/main/cpp/skyline/gpu/buffer.cpp @@ -312,12 +312,15 @@ namespace skyline::gpu { RefreshGpuWritesActiveDirect(true, flushHostCallback); if (directTrackedShadowActive && RefreshGpuReadsActiveDirect()) { - size_t curOffset{offset}; - while (curOffset != data.size() + offset) { - auto result{directTrackedWrites.Query(curOffset)}; + size_t dstOffset{}; + while (dstOffset != data.size()) { + auto srcOffset{dstOffset + offset}; + auto dstRemaining{data.size() - dstOffset}; + auto result{directTrackedWrites.Query(srcOffset)}; + auto size{result.size ? std::min(result.size, dstRemaining) : dstRemaining}; auto srcData{result.enclosed ? directTrackedShadow.data() : mirror.data()}; - std::memcpy(data.data() + curOffset - offset, srcData + curOffset, result.size); - curOffset += result.size; + std::memcpy(data.data() + dstOffset, srcData + srcOffset, size); + dstOffset += size; } } else [[likely]] { std::memcpy(data.data(), mirror.data() + offset, data.size());