From 49478e178af79b0e87982e6b2a617f1f679a0b3d Mon Sep 17 00:00:00 2001 From: Billy Laws Date: Wed, 31 Aug 2022 14:55:22 +0100 Subject: [PATCH] Avoid redundantly syncing buffers before every Write in an execution This isn't a guarantee provided by actual HW so we don't need to provide it either, the sync can be skipped once the buffer already been synced at least once within the execution. --- app/src/main/cpp/skyline/gpu/buffer.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/app/src/main/cpp/skyline/gpu/buffer.cpp b/app/src/main/cpp/skyline/gpu/buffer.cpp index 693fe230..b7b3c477 100644 --- a/app/src/main/cpp/skyline/gpu/buffer.cpp +++ b/app/src/main/cpp/skyline/gpu/buffer.cpp @@ -231,13 +231,19 @@ namespace skyline::gpu { std::scoped_lock lock{stateMutex}; // Syncs in both directions to ensure correct ordering of writes - if (dirtyState == DirtyState::CpuDirty) - SynchronizeHost(); - else if (dirtyState == DirtyState::GpuDirty) + if (dirtyState == DirtyState::GpuDirty) SynchronizeGuestImmediate(isFirstUsage, flushHostCallback); + if (dirtyState == DirtyState::CpuDirty && SequencedCpuBackingWritesBlocked()) + // If the buffer is used in sequence directly on the GPU, SynchronizeHost before modifying the mirror contents to ensure proper sequencing. This write will then be sequenced on the GPU instead (the buffer will be kept clean for the rest of the execution due to gpuCopyCallback blocking all writes) + SynchronizeHost(); + std::memcpy(mirror.data() + offset, data.data(), data.size()); // Always copy to mirror since any CPU side reads will need the up-to-date contents + if (dirtyState == DirtyState::CpuDirty && !SequencedCpuBackingWritesBlocked()) + // Skip updating backing if the changes are gonna be updated later by SynchroniseHost in executor anyway + return false; + if (!SequencedCpuBackingWritesBlocked() && PollFence()) { // We can write directly to the backing as long as this resource isn't being actively used by a past workload (in the current context or another) std::memcpy(backing.data() + offset, data.data(), data.size()); @@ -269,8 +275,6 @@ namespace skyline::gpu { // Bail out if buffer cannot be synced, we don't know the contents ahead of time so the sequence is indeterminate return {}; - SynchronizeHost(); // Ensure that the returned mirror is fully up-to-date by performing a CPU -> GPU sync - return {sequenceNumber, mirror}; }