summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/video_core/CMakeLists.txt3
-rw-r--r--src/video_core/fence_manager.h97
-rw-r--r--src/video_core/renderer_opengl/gl_fence_manager.cpp55
-rw-r--r--src/video_core/renderer_opengl/gl_fence_manager.h47
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp27
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h2
6 files changed, 208 insertions, 23 deletions
diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt
index 258d58eba..9a3f568f9 100644
--- a/src/video_core/CMakeLists.txt
+++ b/src/video_core/CMakeLists.txt
@@ -23,6 +23,7 @@ add_library(video_core STATIC
23 engines/shader_bytecode.h 23 engines/shader_bytecode.h
24 engines/shader_header.h 24 engines/shader_header.h
25 engines/shader_type.h 25 engines/shader_type.h
26 fence_manager.h
26 gpu.cpp 27 gpu.cpp
27 gpu.h 28 gpu.h
28 gpu_asynch.cpp 29 gpu_asynch.cpp
@@ -51,6 +52,8 @@ add_library(video_core STATIC
51 renderer_opengl/gl_buffer_cache.h 52 renderer_opengl/gl_buffer_cache.h
52 renderer_opengl/gl_device.cpp 53 renderer_opengl/gl_device.cpp
53 renderer_opengl/gl_device.h 54 renderer_opengl/gl_device.h
55 renderer_opengl/gl_fence_manager.cpp
56 renderer_opengl/gl_fence_manager.h
54 renderer_opengl/gl_framebuffer_cache.cpp 57 renderer_opengl/gl_framebuffer_cache.cpp
55 renderer_opengl/gl_framebuffer_cache.h 58 renderer_opengl/gl_framebuffer_cache.h
56 renderer_opengl/gl_rasterizer.cpp 59 renderer_opengl/gl_rasterizer.cpp
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
diff --git a/src/video_core/renderer_opengl/gl_fence_manager.cpp b/src/video_core/renderer_opengl/gl_fence_manager.cpp
new file mode 100644
index 000000000..4517ef150
--- /dev/null
+++ b/src/video_core/renderer_opengl/gl_fence_manager.cpp
@@ -0,0 +1,55 @@
1// Copyright 2020 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "common/assert.h"
6
7#include "video_core/renderer_opengl/gl_fence_manager.h"
8
9namespace OpenGL {
10
11GLInnerFence::GLInnerFence(GPUVAddr address, u32 payload)
12 : VideoCommon::FenceBase(address, payload), sync_object{} {}
13
14GLInnerFence::~GLInnerFence() = default;
15
16void GLInnerFence::Queue() {
17 ASSERT(sync_object.handle == 0);
18 sync_object.Create();
19}
20
21bool GLInnerFence::IsSignaled() const {
22 ASSERT(sync_object.handle != 0);
23 GLsizei length;
24 GLint sync_status;
25 glGetSynciv(sync_object.handle, GL_SYNC_STATUS, sizeof(GLint), &length, &sync_status);
26 return sync_status == GL_SIGNALED;
27}
28
29void GLInnerFence::Wait() {
30 ASSERT(sync_object.handle != 0);
31 while (glClientWaitSync(sync_object.handle, 0, 1000) == GL_TIMEOUT_EXPIRED)
32 ;
33}
34
35FenceManagerOpenGL::FenceManagerOpenGL(Core::System& system, VideoCore::RasterizerInterface& rasterizer,
36 TextureCacheOpenGL& texture_cache)
37 : GenericFenceManager(system, rasterizer, texture_cache) {}
38
39Fence FenceManagerOpenGL::CreateFence(GPUVAddr addr, u32 value) {
40 return std::make_shared<GLInnerFence>(addr, value);
41}
42
43void FenceManagerOpenGL::QueueFence(Fence& fence) {
44 fence->Queue();
45}
46
47bool FenceManagerOpenGL::IsFenceSignaled(Fence& fence) {
48 return fence->IsSignaled();
49}
50
51void FenceManagerOpenGL::WaitFence(Fence& fence) {
52 fence->Wait();
53}
54
55} // namespace OpenGL
diff --git a/src/video_core/renderer_opengl/gl_fence_manager.h b/src/video_core/renderer_opengl/gl_fence_manager.h
new file mode 100644
index 000000000..3cfa8b1d0
--- /dev/null
+++ b/src/video_core/renderer_opengl/gl_fence_manager.h
@@ -0,0 +1,47 @@
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 <memory>
8#include <glad/glad.h>
9
10#include "common/common_types.h"
11#include "video_core/fence_manager.h"
12#include "video_core/renderer_opengl/gl_resource_manager.h"
13#include "video_core/renderer_opengl/gl_texture_cache.h"
14
15namespace OpenGL {
16
17class GLInnerFence : public VideoCommon::FenceBase {
18public:
19 GLInnerFence(GPUVAddr address, u32 payload);
20 ~GLInnerFence();
21
22 void Queue();
23
24 bool IsSignaled() const;
25
26 void Wait();
27
28private:
29 OGLSync sync_object;
30};
31
32using Fence = std::shared_ptr<GLInnerFence>;
33using GenericFenceManager = VideoCommon::FenceManager<Fence, TextureCacheOpenGL>;
34
35class FenceManagerOpenGL final : public GenericFenceManager {
36public:
37 FenceManagerOpenGL(Core::System& system, VideoCore::RasterizerInterface& rasterizer,
38 TextureCacheOpenGL& texture_cache);
39
40protected:
41 Fence CreateFence(GPUVAddr addr, u32 value) override;
42 void QueueFence(Fence& fence) override;
43 bool IsFenceSignaled(Fence& fence) override;
44 void WaitFence(Fence& fence) override;
45};
46
47} // namespace OpenGL
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 93bb33e8c..35bed444f 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -101,7 +101,8 @@ RasterizerOpenGL::RasterizerOpenGL(Core::System& system, Core::Frontend::EmuWind
101 : RasterizerAccelerated{system.Memory()}, texture_cache{system, *this, device, state_tracker}, 101 : RasterizerAccelerated{system.Memory()}, texture_cache{system, *this, device, state_tracker},
102 shader_cache{*this, system, emu_window, device}, query_cache{system, *this}, system{system}, 102 shader_cache{*this, system, emu_window, device}, query_cache{system, *this}, system{system},
103 screen_info{info}, program_manager{program_manager}, state_tracker{state_tracker}, 103 screen_info{info}, program_manager{program_manager}, state_tracker{state_tracker},
104 buffer_cache{*this, system, device, STREAM_BUFFER_SIZE} { 104 buffer_cache{*this, system, device, STREAM_BUFFER_SIZE}, fence_manager{system, *this,
105 texture_cache} {
105 CheckExtensions(); 106 CheckExtensions();
106} 107}
107 108
@@ -677,31 +678,11 @@ void RasterizerOpenGL::SyncGuestHost() {
677} 678}
678 679
679void RasterizerOpenGL::SignalFence(GPUVAddr addr, u32 value) { 680void RasterizerOpenGL::SignalFence(GPUVAddr addr, u32 value) {
680 if (!fences.empty()) { 681 fence_manager.SignalFence(addr, value);
681 const std::pair<GPUVAddr, u32>& current_fence = fences.front();
682 const auto [address, payload] = current_fence;
683 texture_cache.PopAsyncFlushes();
684 auto& gpu{system.GPU()};
685 auto& memory_manager{gpu.MemoryManager()};
686 memory_manager.Write<u32>(address, payload);
687 fences.pop_front();
688 }
689 fences.emplace_back(addr, value);
690 texture_cache.CommitAsyncFlushes();
691 FlushCommands();
692 SyncGuestHost();
693} 682}
694 683
695void RasterizerOpenGL::ReleaseFences() { 684void RasterizerOpenGL::ReleaseFences() {
696 while (!fences.empty()) { 685 fence_manager.WaitPendingFences();
697 const std::pair<GPUVAddr, u32>& current_fence = fences.front();
698 const auto [address, payload] = current_fence;
699 texture_cache.PopAsyncFlushes();
700 auto& gpu{system.GPU()};
701 auto& memory_manager{gpu.MemoryManager()};
702 memory_manager.Write<u32>(address, payload);
703 fences.pop_front();
704 }
705} 686}
706 687
707void RasterizerOpenGL::FlushAndInvalidateRegion(VAddr addr, u64 size) { 688void RasterizerOpenGL::FlushAndInvalidateRegion(VAddr addr, u64 size) {
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index 486a154ad..6d173a922 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -23,6 +23,7 @@
23#include "video_core/rasterizer_interface.h" 23#include "video_core/rasterizer_interface.h"
24#include "video_core/renderer_opengl/gl_buffer_cache.h" 24#include "video_core/renderer_opengl/gl_buffer_cache.h"
25#include "video_core/renderer_opengl/gl_device.h" 25#include "video_core/renderer_opengl/gl_device.h"
26#include "video_core/renderer_opengl/gl_fence_manager.h"
26#include "video_core/renderer_opengl/gl_framebuffer_cache.h" 27#include "video_core/renderer_opengl/gl_framebuffer_cache.h"
27#include "video_core/renderer_opengl/gl_query_cache.h" 28#include "video_core/renderer_opengl/gl_query_cache.h"
28#include "video_core/renderer_opengl/gl_resource_manager.h" 29#include "video_core/renderer_opengl/gl_resource_manager.h"
@@ -226,6 +227,7 @@ private:
226 SamplerCacheOpenGL sampler_cache; 227 SamplerCacheOpenGL sampler_cache;
227 FramebufferCacheOpenGL framebuffer_cache; 228 FramebufferCacheOpenGL framebuffer_cache;
228 QueryCache query_cache; 229 QueryCache query_cache;
230 FenceManagerOpenGL fence_manager;
229 231
230 Core::System& system; 232 Core::System& system;
231 ScreenInfo& screen_info; 233 ScreenInfo& screen_info;