summaryrefslogtreecommitdiff
path: root/src/video_core/fence_manager.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core/fence_manager.h')
-rw-r--r--src/video_core/fence_manager.h97
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 @@
1// Copyright 2020 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <algorithm>
8#include <array>
9#include <queue>
10#include <memory>
11
12#include "common/assert.h"
13#include "common/common_types.h"
14#include "core/core.h"
15#include "core/memory.h"
16#include "core/settings.h"
17#include "video_core/gpu.h"
18#include "video_core/memory_manager.h"
19#include "video_core/rasterizer_interface.h"
20
21namespace VideoCommon {
22
23class FenceBase {
24public:
25 FenceBase(GPUVAddr address, u32 payload) : address{address}, payload{payload} {}
26
27 constexpr GPUVAddr GetAddress() const {
28 return address;
29 }
30
31 constexpr u32 GetPayload() const {
32 return payload;
33 }
34
35private:
36 GPUVAddr address;
37 u32 payload;
38};
39
40template <typename TFence, typename TTextureCache>
41class FenceManager {
42public:
43 void SignalFence(GPUVAddr addr, u32 value) {
44 TryReleasePendingFences();
45 TFence new_fence = CreateFence(addr, value);
46 QueueFence(new_fence);
47 fences.push(new_fence);
48 texture_cache.CommitAsyncFlushes();
49 rasterizer.FlushCommands();
50 rasterizer.SyncGuestHost();
51 }
52
53 void WaitPendingFences() {
54 while (!fences.empty()) {
55 TFence& current_fence = fences.front();
56 WaitFence(current_fence);
57 texture_cache.PopAsyncFlushes();
58 auto& gpu{system.GPU()};
59 auto& memory_manager{gpu.MemoryManager()};
60 memory_manager.Write<u32>(current_fence->GetAddress(), current_fence->GetPayload());
61 fences.pop();
62 }
63 }
64
65protected:
66 FenceManager(Core::System& system, VideoCore::RasterizerInterface& rasterizer,
67 TTextureCache& texture_cache)
68 : system{system}, rasterizer{rasterizer}, texture_cache{texture_cache} {}
69
70 virtual TFence CreateFence(GPUVAddr addr, u32 value) = 0;
71 virtual void QueueFence(TFence& fence) = 0;
72 virtual bool IsFenceSignaled(TFence& fence) = 0;
73 virtual void WaitFence(TFence& fence) = 0;
74
75 Core::System& system;
76 VideoCore::RasterizerInterface& rasterizer;
77 TTextureCache& texture_cache;
78
79private:
80 void TryReleasePendingFences() {
81 while (!fences.empty()) {
82 TFence& current_fence = fences.front();
83 if (!IsFenceSignaled(current_fence)) {
84 return;
85 }
86 texture_cache.PopAsyncFlushes();
87 auto& gpu{system.GPU()};
88 auto& memory_manager{gpu.MemoryManager()};
89 memory_manager.Write<u32>(current_fence->GetAddress(), current_fence->GetPayload());
90 fences.pop();
91 }
92 }
93
94 std::queue<TFence> fences;
95};
96
97} // namespace VideoCommon