diff --git a/src/SharpEmu.Libs/Gpu/Vulkan/VulkanGuestGpuBackend.cs b/src/SharpEmu.Libs/Gpu/Vulkan/VulkanGuestGpuBackend.cs index 2d8eec6..5ca67cc 100644 --- a/src/SharpEmu.Libs/Gpu/Vulkan/VulkanGuestGpuBackend.cs +++ b/src/SharpEmu.Libs/Gpu/Vulkan/VulkanGuestGpuBackend.cs @@ -66,6 +66,9 @@ internal sealed class VulkanGuestGpuBackend : IGuestGpuBackend public IdleOutcome SubmitDone(ICpuMemory memory) => VulkanVideoPresenter.SubmitDone(memory); + public void RunAfterPendingCommandStreams(Action work) => + VulkanVideoPresenter.RunAfterPendingCommandStreams(work); + public void RegisterKnownDisplayBuffer(ulong address, uint guestFormat) => VulkanVideoPresenter.RegisterKnownDisplayBuffer(address, guestFormat); diff --git a/src/SharpEmu.Libs/VideoOut/VulkanVideoPresenter.CommandStream.cs b/src/SharpEmu.Libs/VideoOut/VulkanVideoPresenter.CommandStream.cs index 194b952..36e741d 100644 --- a/src/SharpEmu.Libs/VideoOut/VulkanVideoPresenter.CommandStream.cs +++ b/src/SharpEmu.Libs/VideoOut/VulkanVideoPresenter.CommandStream.cs @@ -72,6 +72,26 @@ internal static unsafe partial class VulkanVideoPresenter ? testStream.Done() : IdleOutcome.Completed; + public static void RunAfterPendingCommandStreams(Action work) + { + ArgumentNullException.ThrowIfNull(work); + if (TryGetActivePresenter(out var presenter)) + { + if (presenter.Relay.TryRunAfterAcceptedCommandStreams(work)) + { + return; + } + + if (!HostSessionControl.IsShutdownRequested && !Volatile.Read(ref _closed) && + !Volatile.Read(ref _presenterCloseRequested)) + { + throw SubmissionScheduler.Fatal("The GPU worker rejected an ordered video-out state change."); + } + } + + work(); + } + // The blocked heads of the stream this memory submits to; null when no stream exists for it. internal static BlockedSnapshot? SnapshotBlockedCommandStream(ICpuMemory? memory) {