summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/video_core/buffer_cache/buffer_cache.h7
-rw-r--r--src/video_core/engines/maxwell_3d.cpp4
-rw-r--r--src/video_core/fence_manager.h58
-rw-r--r--src/video_core/rasterizer_interface.h7
-rw-r--r--src/video_core/renderer_opengl/gl_fence_manager.cpp24
-rw-r--r--src/video_core/renderer_opengl/gl_fence_manager.h6
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp13
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h3
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.cpp16
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.h3
-rw-r--r--src/video_core/texture_cache/texture_cache.h7
11 files changed, 123 insertions, 25 deletions
diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h
index 06fb931d7..54c75ca4e 100644
--- a/src/video_core/buffer_cache/buffer_cache.h
+++ b/src/video_core/buffer_cache/buffer_cache.h
@@ -229,6 +229,13 @@ public:
229 return true; 229 return true;
230 } 230 }
231 231
232 bool HasUncommitedFlushes() {
233 if (uncommited_flushes) {
234 return true;
235 }
236 return false;
237 }
238
232 void PopAsyncFlushes() { 239 void PopAsyncFlushes() {
233 if (commited_flushes.empty()) { 240 if (commited_flushes.empty()) {
234 return; 241 return;
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp
index a7e951433..2824ed707 100644
--- a/src/video_core/engines/maxwell_3d.cpp
+++ b/src/video_core/engines/maxwell_3d.cpp
@@ -405,7 +405,7 @@ void Maxwell3D::ProcessQueryGet() {
405 switch (regs.query.query_get.operation) { 405 switch (regs.query.query_get.operation) {
406 case Regs::QueryOperation::Release: 406 case Regs::QueryOperation::Release:
407 if (regs.query.query_get.fence == 1) { 407 if (regs.query.query_get.fence == 1) {
408 rasterizer.SignalFence(regs.query.QueryAddress(), regs.query.query_sequence); 408 rasterizer.SignalSemaphore(regs.query.QueryAddress(), regs.query.query_sequence);
409 } else { 409 } else {
410 StampQueryResult(regs.query.query_sequence, regs.query.query_get.short_query == 0); 410 StampQueryResult(regs.query.query_sequence, regs.query.query_get.short_query == 0);
411 } 411 }
@@ -487,7 +487,7 @@ void Maxwell3D::ProcessSyncPoint() {
487 const u32 increment = regs.sync_info.increment.Value(); 487 const u32 increment = regs.sync_info.increment.Value();
488 [[maybe_unused]] const u32 cache_flush = regs.sync_info.unknown.Value(); 488 [[maybe_unused]] const u32 cache_flush = regs.sync_info.unknown.Value();
489 if (increment) { 489 if (increment) {
490 system.GPU().IncrementSyncPoint(sync_point); 490 rasterizer.SignalSyncPoint(sync_point);
491 } 491 }
492} 492}
493 493
diff --git a/src/video_core/fence_manager.h b/src/video_core/fence_manager.h
index 72ee50955..417cb113f 100644
--- a/src/video_core/fence_manager.h
+++ b/src/video_core/fence_manager.h
@@ -22,7 +22,11 @@ namespace VideoCommon {
22 22
23class FenceBase { 23class FenceBase {
24public: 24public:
25 FenceBase(GPUVAddr address, u32 payload) : address{address}, payload{payload} {} 25 FenceBase(u32 payload, bool is_stubbed)
26 : address{}, payload{payload}, is_semaphore{false}, is_stubbed{is_stubbed} {}
27
28 FenceBase(GPUVAddr address, u32 payload, bool is_stubbed)
29 : address{address}, payload{payload}, is_semaphore{true}, is_stubbed{is_stubbed} {}
26 30
27 constexpr GPUVAddr GetAddress() const { 31 constexpr GPUVAddr GetAddress() const {
28 return address; 32 return address;
@@ -32,22 +36,49 @@ public:
32 return payload; 36 return payload;
33 } 37 }
34 38
39 constexpr bool IsSemaphore() const {
40 return is_semaphore;
41 }
42
35private: 43private:
36 GPUVAddr address; 44 GPUVAddr address;
37 u32 payload; 45 u32 payload;
46 bool is_semaphore;
47
48protected:
49 bool is_stubbed;
38}; 50};
39 51
40template <typename TFence, typename TTextureCache, typename TTBufferCache> 52template <typename TFence, typename TTextureCache, typename TTBufferCache>
41class FenceManager { 53class FenceManager {
42public: 54public:
43 void SignalFence(GPUVAddr addr, u32 value) { 55 void SignalSemaphore(GPUVAddr addr, u32 value) {
44 TryReleasePendingFences(); 56 TryReleasePendingFences();
57 bool should_flush = texture_cache.HasUncommitedFlushes();
58 should_flush |= buffer_cache.HasUncommitedFlushes();
45 texture_cache.CommitAsyncFlushes(); 59 texture_cache.CommitAsyncFlushes();
46 buffer_cache.CommitAsyncFlushes(); 60 buffer_cache.CommitAsyncFlushes();
47 TFence new_fence = CreateFence(addr, value); 61 TFence new_fence = CreateFence(addr, value, !should_flush);
48 fences.push(new_fence); 62 fences.push(new_fence);
49 QueueFence(new_fence); 63 QueueFence(new_fence);
50 rasterizer.FlushCommands(); 64 if (should_flush) {
65 rasterizer.FlushCommands();
66 }
67 rasterizer.SyncGuestHost();
68 }
69
70 void SignalSyncPoint(u32 value) {
71 TryReleasePendingFences();
72 bool should_flush = texture_cache.HasUncommitedFlushes();
73 should_flush |= buffer_cache.HasUncommitedFlushes();
74 texture_cache.CommitAsyncFlushes();
75 buffer_cache.CommitAsyncFlushes();
76 TFence new_fence = CreateFence(value, !should_flush);
77 fences.push(new_fence);
78 QueueFence(new_fence);
79 if (should_flush) {
80 rasterizer.FlushCommands();
81 }
51 rasterizer.SyncGuestHost(); 82 rasterizer.SyncGuestHost();
52 } 83 }
53 84
@@ -62,8 +93,12 @@ public:
62 texture_cache.PopAsyncFlushes(); 93 texture_cache.PopAsyncFlushes();
63 buffer_cache.PopAsyncFlushes(); 94 buffer_cache.PopAsyncFlushes();
64 auto& gpu{system.GPU()}; 95 auto& gpu{system.GPU()};
65 auto& memory_manager{gpu.MemoryManager()}; 96 if (current_fence->IsSemaphore()) {
66 memory_manager.Write<u32>(current_fence->GetAddress(), current_fence->GetPayload()); 97 auto& memory_manager{gpu.MemoryManager()};
98 memory_manager.Write<u32>(current_fence->GetAddress(), current_fence->GetPayload());
99 } else {
100 gpu.IncrementSyncPoint(current_fence->GetPayload());
101 }
67 fences.pop(); 102 fences.pop();
68 } 103 }
69 } 104 }
@@ -74,7 +109,8 @@ protected:
74 : system{system}, rasterizer{rasterizer}, texture_cache{texture_cache}, buffer_cache{ 109 : system{system}, rasterizer{rasterizer}, texture_cache{texture_cache}, buffer_cache{
75 buffer_cache} {} 110 buffer_cache} {}
76 111
77 virtual TFence CreateFence(GPUVAddr addr, u32 value) = 0; 112 virtual TFence CreateFence(u32 value, bool is_stubbed) = 0;
113 virtual TFence CreateFence(GPUVAddr addr, u32 value, bool is_stubbed) = 0;
78 virtual void QueueFence(TFence& fence) = 0; 114 virtual void QueueFence(TFence& fence) = 0;
79 virtual bool IsFenceSignaled(TFence& fence) = 0; 115 virtual bool IsFenceSignaled(TFence& fence) = 0;
80 virtual void WaitFence(TFence& fence) = 0; 116 virtual void WaitFence(TFence& fence) = 0;
@@ -96,8 +132,12 @@ private:
96 texture_cache.PopAsyncFlushes(); 132 texture_cache.PopAsyncFlushes();
97 buffer_cache.PopAsyncFlushes(); 133 buffer_cache.PopAsyncFlushes();
98 auto& gpu{system.GPU()}; 134 auto& gpu{system.GPU()};
99 auto& memory_manager{gpu.MemoryManager()}; 135 if (current_fence->IsSemaphore()) {
100 memory_manager.Write<u32>(current_fence->GetAddress(), current_fence->GetPayload()); 136 auto& memory_manager{gpu.MemoryManager()};
137 memory_manager.Write<u32>(current_fence->GetAddress(), current_fence->GetPayload());
138 } else {
139 gpu.IncrementSyncPoint(current_fence->GetPayload());
140 }
101 fences.pop(); 141 fences.pop();
102 } 142 }
103 } 143 }
diff --git a/src/video_core/rasterizer_interface.h b/src/video_core/rasterizer_interface.h
index b49f15df2..4e9c8fb59 100644
--- a/src/video_core/rasterizer_interface.h
+++ b/src/video_core/rasterizer_interface.h
@@ -49,8 +49,11 @@ public:
49 /// Records a GPU query and caches it 49 /// Records a GPU query and caches it
50 virtual void Query(GPUVAddr gpu_addr, QueryType type, std::optional<u64> timestamp) = 0; 50 virtual void Query(GPUVAddr gpu_addr, QueryType type, std::optional<u64> timestamp) = 0;
51 51
52 /// Signal a GPU based fence 52 /// Signal a GPU based semaphore as a fence
53 virtual void SignalFence(GPUVAddr addr, u32 value) = 0; 53 virtual void SignalSemaphore(GPUVAddr addr, u32 value) = 0;
54
55 /// Signal a GPU based syncpoint as a fence
56 virtual void SignalSyncPoint(u32 value) = 0;
54 57
55 /// Release all pending fences. 58 /// Release all pending fences.
56 virtual void ReleaseFences() = 0; 59 virtual void ReleaseFences() = 0;
diff --git a/src/video_core/renderer_opengl/gl_fence_manager.cpp b/src/video_core/renderer_opengl/gl_fence_manager.cpp
index 69dd3211b..579c03a1e 100644
--- a/src/video_core/renderer_opengl/gl_fence_manager.cpp
+++ b/src/video_core/renderer_opengl/gl_fence_manager.cpp
@@ -8,17 +8,26 @@
8 8
9namespace OpenGL { 9namespace OpenGL {
10 10
11GLInnerFence::GLInnerFence(GPUVAddr address, u32 payload) 11GLInnerFence::GLInnerFence(u32 payload, bool is_stubbed)
12 : VideoCommon::FenceBase(address, payload), sync_object{} {} 12 : VideoCommon::FenceBase(payload, is_stubbed), sync_object{} {}
13
14GLInnerFence::GLInnerFence(GPUVAddr address, u32 payload, bool is_stubbed)
15 : VideoCommon::FenceBase(address, payload, is_stubbed), sync_object{} {}
13 16
14GLInnerFence::~GLInnerFence() = default; 17GLInnerFence::~GLInnerFence() = default;
15 18
16void GLInnerFence::Queue() { 19void GLInnerFence::Queue() {
20 if (is_stubbed) {
21 return;
22 }
17 ASSERT(sync_object.handle == 0); 23 ASSERT(sync_object.handle == 0);
18 sync_object.Create(); 24 sync_object.Create();
19} 25}
20 26
21bool GLInnerFence::IsSignaled() const { 27bool GLInnerFence::IsSignaled() const {
28 if (is_stubbed) {
29 return true;
30 }
22 ASSERT(sync_object.handle != 0); 31 ASSERT(sync_object.handle != 0);
23 GLsizei length; 32 GLsizei length;
24 GLint sync_status; 33 GLint sync_status;
@@ -27,6 +36,9 @@ bool GLInnerFence::IsSignaled() const {
27} 36}
28 37
29void GLInnerFence::Wait() { 38void GLInnerFence::Wait() {
39 if (is_stubbed) {
40 return;
41 }
30 ASSERT(sync_object.handle != 0); 42 ASSERT(sync_object.handle != 0);
31 while (glClientWaitSync(sync_object.handle, 0, 1000) == GL_TIMEOUT_EXPIRED) 43 while (glClientWaitSync(sync_object.handle, 0, 1000) == GL_TIMEOUT_EXPIRED)
32 ; 44 ;
@@ -36,8 +48,12 @@ FenceManagerOpenGL::FenceManagerOpenGL(Core::System& system, VideoCore::Rasteriz
36 TextureCacheOpenGL& texture_cache, OGLBufferCache& buffer_cache) 48 TextureCacheOpenGL& texture_cache, OGLBufferCache& buffer_cache)
37 : GenericFenceManager(system, rasterizer, texture_cache, buffer_cache) {} 49 : GenericFenceManager(system, rasterizer, texture_cache, buffer_cache) {}
38 50
39Fence FenceManagerOpenGL::CreateFence(GPUVAddr addr, u32 value) { 51Fence FenceManagerOpenGL::CreateFence(u32 value, bool is_stubbed) {
40 return std::make_shared<GLInnerFence>(addr, value); 52 return std::make_shared<GLInnerFence>(value, is_stubbed);
53}
54
55Fence FenceManagerOpenGL::CreateFence(GPUVAddr addr, u32 value, bool is_stubbed) {
56 return std::make_shared<GLInnerFence>(addr, value, is_stubbed);
41} 57}
42 58
43void FenceManagerOpenGL::QueueFence(Fence& fence) { 59void FenceManagerOpenGL::QueueFence(Fence& fence) {
diff --git a/src/video_core/renderer_opengl/gl_fence_manager.h b/src/video_core/renderer_opengl/gl_fence_manager.h
index b48d5eaa0..ba48d2f84 100644
--- a/src/video_core/renderer_opengl/gl_fence_manager.h
+++ b/src/video_core/renderer_opengl/gl_fence_manager.h
@@ -17,7 +17,8 @@ namespace OpenGL {
17 17
18class GLInnerFence : public VideoCommon::FenceBase { 18class GLInnerFence : public VideoCommon::FenceBase {
19public: 19public:
20 GLInnerFence(GPUVAddr address, u32 payload); 20 GLInnerFence(u32 payload, bool is_stubbed);
21 GLInnerFence(GPUVAddr address, u32 payload, bool is_stubbed);
21 ~GLInnerFence(); 22 ~GLInnerFence();
22 23
23 void Queue(); 24 void Queue();
@@ -39,7 +40,8 @@ public:
39 TextureCacheOpenGL& texture_cache, OGLBufferCache& buffer_cache); 40 TextureCacheOpenGL& texture_cache, OGLBufferCache& buffer_cache);
40 41
41protected: 42protected:
42 Fence CreateFence(GPUVAddr addr, u32 value) override; 43 Fence CreateFence(u32 value, bool is_stubbed) override;
44 Fence CreateFence(GPUVAddr addr, u32 value, bool is_stubbed) override;
43 void QueueFence(Fence& fence) override; 45 void QueueFence(Fence& fence) override;
44 bool IsFenceSignaled(Fence& fence) override; 46 bool IsFenceSignaled(Fence& fence) override;
45 void WaitFence(Fence& fence) override; 47 void WaitFence(Fence& fence) override;
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 88914828c..e52e5961f 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -683,14 +683,23 @@ void RasterizerOpenGL::SyncGuestHost() {
683 buffer_cache.SyncGuestHost(); 683 buffer_cache.SyncGuestHost();
684} 684}
685 685
686void RasterizerOpenGL::SignalFence(GPUVAddr addr, u32 value) { 686void RasterizerOpenGL::SignalSemaphore(GPUVAddr addr, u32 value) {
687 auto& gpu{system.GPU()}; 687 auto& gpu{system.GPU()};
688 if (!gpu.IsAsync()) { 688 if (!gpu.IsAsync()) {
689 auto& memory_manager{gpu.MemoryManager()}; 689 auto& memory_manager{gpu.MemoryManager()};
690 memory_manager.Write<u32>(addr, value); 690 memory_manager.Write<u32>(addr, value);
691 return; 691 return;
692 } 692 }
693 fence_manager.SignalFence(addr, value); 693 fence_manager.SignalSemaphore(addr, value);
694}
695
696void RasterizerOpenGL::SignalSyncPoint(u32 value) {
697 auto& gpu{system.GPU()};
698 if (!gpu.IsAsync()) {
699 gpu.IncrementSyncPoint(value);
700 return;
701 }
702 fence_manager.SignalSyncPoint(value);
694} 703}
695 704
696void RasterizerOpenGL::ReleaseFences() { 705void RasterizerOpenGL::ReleaseFences() {
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index 5c0f88e6f..15e9ff7d7 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -71,7 +71,8 @@ public:
71 void InvalidateRegion(VAddr addr, u64 size) override; 71 void InvalidateRegion(VAddr addr, u64 size) override;
72 void OnCPUWrite(VAddr addr, u64 size) override; 72 void OnCPUWrite(VAddr addr, u64 size) override;
73 void SyncGuestHost() override; 73 void SyncGuestHost() override;
74 void SignalFence(GPUVAddr addr, u32 value) override; 74 void SignalSemaphore(GPUVAddr addr, u32 value) override;
75 void SignalSyncPoint(u32 value) override;
75 void ReleaseFences() override; 76 void ReleaseFences() override;
76 void FlushAndInvalidateRegion(VAddr addr, u64 size) override; 77 void FlushAndInvalidateRegion(VAddr addr, u64 size) override;
77 void FlushCommands() override; 78 void FlushCommands() override;
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
index 1d75a4766..507262c8f 100644
--- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp
+++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
@@ -543,7 +543,7 @@ void RasterizerVulkan::SyncGuestHost() {
543 buffer_cache.SyncGuestHost(); 543 buffer_cache.SyncGuestHost();
544} 544}
545 545
546void RasterizerVulkan::SignalFence(GPUVAddr addr, u32 value) { 546void RasterizerVulkan::SignalSemaphore(GPUVAddr addr, u32 value) {
547 auto& gpu{system.GPU()}; 547 auto& gpu{system.GPU()};
548 auto& memory_manager{gpu.MemoryManager()}; 548 auto& memory_manager{gpu.MemoryManager()};
549 memory_manager.Write<u32>(addr, value); 549 memory_manager.Write<u32>(addr, value);
@@ -553,7 +553,19 @@ void RasterizerVulkan::SignalFence(GPUVAddr addr, u32 value) {
553 memory_manager.Write<u32>(addr, value); 553 memory_manager.Write<u32>(addr, value);
554 return; 554 return;
555 } 555 }
556 fence_manager.SignalFence(addr, value); 556 fence_manager.SignalSemaphore(addr, value);
557 */
558}
559
560void RasterizerVulkan::SignalSyncPoint(u32 value) {
561 auto& gpu{system.GPU()};
562 gpu.IncrementSyncPoint(value);
563 /*
564 if (!gpu.IsAsync()) {
565 gpu.IncrementSyncPoint(value);
566 return;
567 }
568 fence_manager.SignalSyncPoint(value);
557 */ 569 */
558} 570}
559 571
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.h b/src/video_core/renderer_vulkan/vk_rasterizer.h
index 08a9af401..145bdf899 100644
--- a/src/video_core/renderer_vulkan/vk_rasterizer.h
+++ b/src/video_core/renderer_vulkan/vk_rasterizer.h
@@ -122,7 +122,8 @@ public:
122 void InvalidateRegion(VAddr addr, u64 size) override; 122 void InvalidateRegion(VAddr addr, u64 size) override;
123 void OnCPUWrite(VAddr addr, u64 size) override; 123 void OnCPUWrite(VAddr addr, u64 size) override;
124 void SyncGuestHost() override; 124 void SyncGuestHost() override;
125 void SignalFence(GPUVAddr addr, u32 value) override; 125 void SignalSemaphore(GPUVAddr addr, u32 value) override;
126 void SignalSyncPoint(u32 value) override;
126 void ReleaseFences() override; 127 void ReleaseFences() override;
127 void FlushAndInvalidateRegion(VAddr addr, u64 size) override; 128 void FlushAndInvalidateRegion(VAddr addr, u64 size) override;
128 void FlushCommands() override; 129 void FlushCommands() override;
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h
index e1a1edbd2..f3ca1ffd1 100644
--- a/src/video_core/texture_cache/texture_cache.h
+++ b/src/video_core/texture_cache/texture_cache.h
@@ -337,6 +337,13 @@ public:
337 uncommited_flushes.reset(); 337 uncommited_flushes.reset();
338 } 338 }
339 339
340 bool HasUncommitedFlushes() {
341 if (uncommited_flushes) {
342 return true;
343 }
344 return false;
345 }
346
340 bool ShouldWaitAsyncFlushes() { 347 bool ShouldWaitAsyncFlushes() {
341 if (commited_flushes.empty()) { 348 if (commited_flushes.empty()) {
342 return false; 349 return false;