summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Fernando Sahmkow2020-02-18 17:20:39 -0400
committerGravatar Fernando Sahmkow2020-04-22 11:36:15 -0400
commitb10db7e4a5f43414679b7969ea309b1829937a37 (patch)
tree5a2df21d974ee17488ee01960a823ae6f89d9edb /src
parentRasterizer: Document SignalFence & ReleaseFences and setup skeletons on Vulkan. (diff)
downloadyuzu-b10db7e4a5f43414679b7969ea309b1829937a37.tar.gz
yuzu-b10db7e4a5f43414679b7969ea309b1829937a37.tar.xz
yuzu-b10db7e4a5f43414679b7969ea309b1829937a37.zip
FenceManager: Implement async buffer cache flushes on High settings
Diffstat (limited to 'src')
-rw-r--r--src/video_core/buffer_cache/buffer_cache.h50
-rw-r--r--src/video_core/fence_manager.h15
-rw-r--r--src/video_core/gpu_thread.cpp2
-rw-r--r--src/video_core/renderer_opengl/gl_fence_manager.cpp4
-rw-r--r--src/video_core/renderer_opengl/gl_fence_manager.h5
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp3
6 files changed, 69 insertions, 10 deletions
diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h
index df4c0211e..d72df90ef 100644
--- a/src/video_core/buffer_cache/buffer_cache.h
+++ b/src/video_core/buffer_cache/buffer_cache.h
@@ -21,6 +21,7 @@
21#include "common/common_types.h" 21#include "common/common_types.h"
22#include "core/core.h" 22#include "core/core.h"
23#include "core/memory.h" 23#include "core/memory.h"
24#include "core/settings.h"
24#include "video_core/buffer_cache/buffer_block.h" 25#include "video_core/buffer_cache/buffer_block.h"
25#include "video_core/buffer_cache/map_interval.h" 26#include "video_core/buffer_cache/map_interval.h"
26#include "video_core/memory_manager.h" 27#include "video_core/memory_manager.h"
@@ -80,6 +81,9 @@ public:
80 auto map = MapAddress(block, gpu_addr, cpu_addr, size); 81 auto map = MapAddress(block, gpu_addr, cpu_addr, size);
81 if (is_written) { 82 if (is_written) {
82 map->MarkAsModified(true, GetModifiedTicks()); 83 map->MarkAsModified(true, GetModifiedTicks());
84 if (Settings::IsGPULevelHigh() && Settings::values.use_asynchronous_gpu_emulation) {
85 AsyncFlushMap(map);
86 }
83 if (!map->IsWritten()) { 87 if (!map->IsWritten()) {
84 map->MarkAsWritten(true); 88 map->MarkAsWritten(true);
85 MarkRegionAsWritten(map->GetStart(), map->GetEnd() - 1); 89 MarkRegionAsWritten(map->GetStart(), map->GetEnd() - 1);
@@ -193,6 +197,39 @@ public:
193 marked_for_unregister.clear(); 197 marked_for_unregister.clear();
194 } 198 }
195 199
200 void CommitAsyncFlushes() {
201 commited_flushes.push_back(uncommited_flushes);
202 uncommited_flushes.reset();
203 }
204
205 bool ShouldWaitAsyncFlushes() {
206 if (commited_flushes.empty()) {
207 return false;
208 }
209 auto& flush_list = commited_flushes.front();
210 if (!flush_list) {
211 return false;
212 }
213 return true;
214 }
215
216 void PopAsyncFlushes() {
217 if (commited_flushes.empty()) {
218 return;
219 }
220 auto& flush_list = commited_flushes.front();
221 if (!flush_list) {
222 commited_flushes.pop_front();
223 return;
224 }
225 for (MapInterval& map : *flush_list) {
226 if (map->IsRegistered()) {
227 FlushMap(map);
228 }
229 }
230 commited_flushes.pop_front();
231 }
232
196 virtual BufferType GetEmptyBuffer(std::size_t size) = 0; 233 virtual BufferType GetEmptyBuffer(std::size_t size) = 0;
197 234
198protected: 235protected:
@@ -316,6 +353,9 @@ private:
316 MapInterval new_map = CreateMap(new_start, new_end, new_gpu_addr); 353 MapInterval new_map = CreateMap(new_start, new_end, new_gpu_addr);
317 if (modified_inheritance) { 354 if (modified_inheritance) {
318 new_map->MarkAsModified(true, GetModifiedTicks()); 355 new_map->MarkAsModified(true, GetModifiedTicks());
356 if (Settings::IsGPULevelHigh() && Settings::values.use_asynchronous_gpu_emulation) {
357 AsyncFlushMap(new_map);
358 }
319 } 359 }
320 Register(new_map, write_inheritance); 360 Register(new_map, write_inheritance);
321 return new_map; 361 return new_map;
@@ -502,6 +542,13 @@ private:
502 return false; 542 return false;
503 } 543 }
504 544
545 void AsyncFlushMap(MapInterval& map) {
546 if (!uncommited_flushes) {
547 uncommited_flushes = std::make_shared<std::list<MapInterval>>();
548 }
549 uncommited_flushes->push_back(map);
550 }
551
505 VideoCore::RasterizerInterface& rasterizer; 552 VideoCore::RasterizerInterface& rasterizer;
506 Core::System& system; 553 Core::System& system;
507 554
@@ -533,6 +580,9 @@ private:
533 std::vector<u8> staging_buffer; 580 std::vector<u8> staging_buffer;
534 std::list<MapInterval> marked_for_unregister; 581 std::list<MapInterval> marked_for_unregister;
535 582
583 std::shared_ptr<std::list<MapInterval>> uncommited_flushes{};
584 std::list<std::shared_ptr<std::list<MapInterval>>> commited_flushes;
585
536 std::recursive_mutex mutex; 586 std::recursive_mutex mutex;
537}; 587};
538 588
diff --git a/src/video_core/fence_manager.h b/src/video_core/fence_manager.h
index 036f3996c..c4b190503 100644
--- a/src/video_core/fence_manager.h
+++ b/src/video_core/fence_manager.h
@@ -6,8 +6,8 @@
6 6
7#include <algorithm> 7#include <algorithm>
8#include <array> 8#include <array>
9#include <queue>
10#include <memory> 9#include <memory>
10#include <queue>
11 11
12#include "common/assert.h" 12#include "common/assert.h"
13#include "common/common_types.h" 13#include "common/common_types.h"
@@ -37,7 +37,7 @@ private:
37 u32 payload; 37 u32 payload;
38}; 38};
39 39
40template <typename TFence, typename TTextureCache> 40template <typename TFence, typename TTextureCache, typename TTBufferCache>
41class FenceManager { 41class FenceManager {
42public: 42public:
43 void SignalFence(GPUVAddr addr, u32 value) { 43 void SignalFence(GPUVAddr addr, u32 value) {
@@ -46,6 +46,7 @@ public:
46 QueueFence(new_fence); 46 QueueFence(new_fence);
47 fences.push(new_fence); 47 fences.push(new_fence);
48 texture_cache.CommitAsyncFlushes(); 48 texture_cache.CommitAsyncFlushes();
49 buffer_cache.CommitAsyncFlushes();
49 rasterizer.FlushCommands(); 50 rasterizer.FlushCommands();
50 rasterizer.SyncGuestHost(); 51 rasterizer.SyncGuestHost();
51 } 52 }
@@ -54,10 +55,12 @@ public:
54 while (!fences.empty()) { 55 while (!fences.empty()) {
55 TFence& current_fence = fences.front(); 56 TFence& current_fence = fences.front();
56 bool should_wait = texture_cache.ShouldWaitAsyncFlushes(); 57 bool should_wait = texture_cache.ShouldWaitAsyncFlushes();
58 should_wait |= buffer_cache.ShouldWaitAsyncFlushes();
57 if (should_wait) { 59 if (should_wait) {
58 WaitFence(current_fence); 60 WaitFence(current_fence);
59 } 61 }
60 texture_cache.PopAsyncFlushes(); 62 texture_cache.PopAsyncFlushes();
63 buffer_cache.PopAsyncFlushes();
61 auto& gpu{system.GPU()}; 64 auto& gpu{system.GPU()};
62 auto& memory_manager{gpu.MemoryManager()}; 65 auto& memory_manager{gpu.MemoryManager()};
63 memory_manager.Write<u32>(current_fence->GetAddress(), current_fence->GetPayload()); 66 memory_manager.Write<u32>(current_fence->GetAddress(), current_fence->GetPayload());
@@ -67,8 +70,9 @@ public:
67 70
68protected: 71protected:
69 FenceManager(Core::System& system, VideoCore::RasterizerInterface& rasterizer, 72 FenceManager(Core::System& system, VideoCore::RasterizerInterface& rasterizer,
70 TTextureCache& texture_cache) 73 TTextureCache& texture_cache, TTBufferCache& buffer_cache)
71 : system{system}, rasterizer{rasterizer}, texture_cache{texture_cache} {} 74 : system{system}, rasterizer{rasterizer}, texture_cache{texture_cache}, buffer_cache{
75 buffer_cache} {}
72 76
73 virtual TFence CreateFence(GPUVAddr addr, u32 value) = 0; 77 virtual TFence CreateFence(GPUVAddr addr, u32 value) = 0;
74 virtual void QueueFence(TFence& fence) = 0; 78 virtual void QueueFence(TFence& fence) = 0;
@@ -78,16 +82,19 @@ protected:
78 Core::System& system; 82 Core::System& system;
79 VideoCore::RasterizerInterface& rasterizer; 83 VideoCore::RasterizerInterface& rasterizer;
80 TTextureCache& texture_cache; 84 TTextureCache& texture_cache;
85 TTBufferCache& buffer_cache;
81 86
82private: 87private:
83 void TryReleasePendingFences() { 88 void TryReleasePendingFences() {
84 while (!fences.empty()) { 89 while (!fences.empty()) {
85 TFence& current_fence = fences.front(); 90 TFence& current_fence = fences.front();
86 bool should_wait = texture_cache.ShouldWaitAsyncFlushes(); 91 bool should_wait = texture_cache.ShouldWaitAsyncFlushes();
92 should_wait |= buffer_cache.ShouldWaitAsyncFlushes();
87 if (should_wait && !IsFenceSignaled(current_fence)) { 93 if (should_wait && !IsFenceSignaled(current_fence)) {
88 return; 94 return;
89 } 95 }
90 texture_cache.PopAsyncFlushes(); 96 texture_cache.PopAsyncFlushes();
97 buffer_cache.PopAsyncFlushes();
91 auto& gpu{system.GPU()}; 98 auto& gpu{system.GPU()};
92 auto& memory_manager{gpu.MemoryManager()}; 99 auto& memory_manager{gpu.MemoryManager()};
93 memory_manager.Write<u32>(current_fence->GetAddress(), current_fence->GetPayload()); 100 memory_manager.Write<u32>(current_fence->GetAddress(), current_fence->GetPayload());
diff --git a/src/video_core/gpu_thread.cpp b/src/video_core/gpu_thread.cpp
index 1c3ab2145..3e2be00e9 100644
--- a/src/video_core/gpu_thread.cpp
+++ b/src/video_core/gpu_thread.cpp
@@ -81,7 +81,7 @@ void ThreadManager::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) {
81} 81}
82 82
83void ThreadManager::FlushRegion(VAddr addr, u64 size) { 83void ThreadManager::FlushRegion(VAddr addr, u64 size) {
84 if (!Settings::IsGPULevelExtreme()) { 84 if (!Settings::IsGPULevelHigh()) {
85 return; 85 return;
86 } 86 }
87 if (system.Renderer().Rasterizer().MustFlushRegion(addr, size)) { 87 if (system.Renderer().Rasterizer().MustFlushRegion(addr, size)) {
diff --git a/src/video_core/renderer_opengl/gl_fence_manager.cpp b/src/video_core/renderer_opengl/gl_fence_manager.cpp
index 4517ef150..69dd3211b 100644
--- a/src/video_core/renderer_opengl/gl_fence_manager.cpp
+++ b/src/video_core/renderer_opengl/gl_fence_manager.cpp
@@ -33,8 +33,8 @@ void GLInnerFence::Wait() {
33} 33}
34 34
35FenceManagerOpenGL::FenceManagerOpenGL(Core::System& system, VideoCore::RasterizerInterface& rasterizer, 35FenceManagerOpenGL::FenceManagerOpenGL(Core::System& system, VideoCore::RasterizerInterface& rasterizer,
36 TextureCacheOpenGL& texture_cache) 36 TextureCacheOpenGL& texture_cache, OGLBufferCache& buffer_cache)
37 : GenericFenceManager(system, rasterizer, texture_cache) {} 37 : GenericFenceManager(system, rasterizer, texture_cache, buffer_cache) {}
38 38
39Fence FenceManagerOpenGL::CreateFence(GPUVAddr addr, u32 value) { 39Fence FenceManagerOpenGL::CreateFence(GPUVAddr addr, u32 value) {
40 return std::make_shared<GLInnerFence>(addr, value); 40 return std::make_shared<GLInnerFence>(addr, value);
diff --git a/src/video_core/renderer_opengl/gl_fence_manager.h b/src/video_core/renderer_opengl/gl_fence_manager.h
index 3cfa8b1d0..b48d5eaa0 100644
--- a/src/video_core/renderer_opengl/gl_fence_manager.h
+++ b/src/video_core/renderer_opengl/gl_fence_manager.h
@@ -9,6 +9,7 @@
9 9
10#include "common/common_types.h" 10#include "common/common_types.h"
11#include "video_core/fence_manager.h" 11#include "video_core/fence_manager.h"
12#include "video_core/renderer_opengl/gl_buffer_cache.h"
12#include "video_core/renderer_opengl/gl_resource_manager.h" 13#include "video_core/renderer_opengl/gl_resource_manager.h"
13#include "video_core/renderer_opengl/gl_texture_cache.h" 14#include "video_core/renderer_opengl/gl_texture_cache.h"
14 15
@@ -30,12 +31,12 @@ private:
30}; 31};
31 32
32using Fence = std::shared_ptr<GLInnerFence>; 33using Fence = std::shared_ptr<GLInnerFence>;
33using GenericFenceManager = VideoCommon::FenceManager<Fence, TextureCacheOpenGL>; 34using GenericFenceManager = VideoCommon::FenceManager<Fence, TextureCacheOpenGL, OGLBufferCache>;
34 35
35class FenceManagerOpenGL final : public GenericFenceManager { 36class FenceManagerOpenGL final : public GenericFenceManager {
36public: 37public:
37 FenceManagerOpenGL(Core::System& system, VideoCore::RasterizerInterface& rasterizer, 38 FenceManagerOpenGL(Core::System& system, VideoCore::RasterizerInterface& rasterizer,
38 TextureCacheOpenGL& texture_cache); 39 TextureCacheOpenGL& texture_cache, OGLBufferCache& buffer_cache);
39 40
40protected: 41protected:
41 Fence CreateFence(GPUVAddr addr, u32 value) override; 42 Fence CreateFence(GPUVAddr addr, u32 value) override;
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index db7eae065..88914828c 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -102,7 +102,8 @@ RasterizerOpenGL::RasterizerOpenGL(Core::System& system, Core::Frontend::EmuWind
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}, fence_manager{system, *this, 104 buffer_cache{*this, system, device, STREAM_BUFFER_SIZE}, fence_manager{system, *this,
105 texture_cache} { 105 texture_cache,
106 buffer_cache} {
106 CheckExtensions(); 107 CheckExtensions();
107} 108}
108 109