diff options
author | Fernando Sahmkow <fsahmkow27@gmail.com> | 2020-02-18 01:19:26 +0100 |
---|---|---|
committer | Fernando Sahmkow <fsahmkow27@gmail.com> | 2020-04-22 17:36:10 +0200 |
commit | 1f345ebe3a5501b50f26f0c5c21cac5d55dd79c1 (patch) | |
tree | d0c9926af3f60d35e3cf06f52e114e57fefea4b8 /src/video_core/fence_manager.h | |
parent | OpenGL: Implement Fencing backend. (diff) | |
download | yuzu-1f345ebe3a5501b50f26f0c5c21cac5d55dd79c1.tar yuzu-1f345ebe3a5501b50f26f0c5c21cac5d55dd79c1.tar.gz yuzu-1f345ebe3a5501b50f26f0c5c21cac5d55dd79c1.tar.bz2 yuzu-1f345ebe3a5501b50f26f0c5c21cac5d55dd79c1.tar.lz yuzu-1f345ebe3a5501b50f26f0c5c21cac5d55dd79c1.tar.xz yuzu-1f345ebe3a5501b50f26f0c5c21cac5d55dd79c1.tar.zst yuzu-1f345ebe3a5501b50f26f0c5c21cac5d55dd79c1.zip |
Diffstat (limited to '')
-rw-r--r-- | src/video_core/fence_manager.h | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/src/video_core/fence_manager.h b/src/video_core/fence_manager.h new file mode 100644 index 000000000..19cec0f66 --- /dev/null +++ b/src/video_core/fence_manager.h @@ -0,0 +1,97 @@ +// Copyright 2020 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include <algorithm> +#include <array> +#include <queue> +#include <memory> + +#include "common/assert.h" +#include "common/common_types.h" +#include "core/core.h" +#include "core/memory.h" +#include "core/settings.h" +#include "video_core/gpu.h" +#include "video_core/memory_manager.h" +#include "video_core/rasterizer_interface.h" + +namespace VideoCommon { + +class FenceBase { +public: + FenceBase(GPUVAddr address, u32 payload) : address{address}, payload{payload} {} + + constexpr GPUVAddr GetAddress() const { + return address; + } + + constexpr u32 GetPayload() const { + return payload; + } + +private: + GPUVAddr address; + u32 payload; +}; + +template <typename TFence, typename TTextureCache> +class FenceManager { +public: + void SignalFence(GPUVAddr addr, u32 value) { + TryReleasePendingFences(); + TFence new_fence = CreateFence(addr, value); + QueueFence(new_fence); + fences.push(new_fence); + texture_cache.CommitAsyncFlushes(); + rasterizer.FlushCommands(); + rasterizer.SyncGuestHost(); + } + + void WaitPendingFences() { + while (!fences.empty()) { + TFence& current_fence = fences.front(); + WaitFence(current_fence); + texture_cache.PopAsyncFlushes(); + auto& gpu{system.GPU()}; + auto& memory_manager{gpu.MemoryManager()}; + memory_manager.Write<u32>(current_fence->GetAddress(), current_fence->GetPayload()); + fences.pop(); + } + } + +protected: + FenceManager(Core::System& system, VideoCore::RasterizerInterface& rasterizer, + TTextureCache& texture_cache) + : system{system}, rasterizer{rasterizer}, texture_cache{texture_cache} {} + + virtual TFence CreateFence(GPUVAddr addr, u32 value) = 0; + virtual void QueueFence(TFence& fence) = 0; + virtual bool IsFenceSignaled(TFence& fence) = 0; + virtual void WaitFence(TFence& fence) = 0; + + Core::System& system; + VideoCore::RasterizerInterface& rasterizer; + TTextureCache& texture_cache; + +private: + void TryReleasePendingFences() { + while (!fences.empty()) { + TFence& current_fence = fences.front(); + if (!IsFenceSignaled(current_fence)) { + return; + } + texture_cache.PopAsyncFlushes(); + auto& gpu{system.GPU()}; + auto& memory_manager{gpu.MemoryManager()}; + memory_manager.Write<u32>(current_fence->GetAddress(), current_fence->GetPayload()); + fences.pop(); + } + } + + std::queue<TFence> fences; +}; + +} // namespace VideoCommon |