summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/video_core/buffer_cache/buffer_cache.h16
-rw-r--r--src/video_core/fence_manager.h24
-rw-r--r--src/video_core/gpu.cpp4
-rw-r--r--src/video_core/rasterizer_interface.h3
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp7
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h1
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.cpp7
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.h1
8 files changed, 57 insertions, 6 deletions
diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h
index dc2b1f447..3faa7e0d0 100644
--- a/src/video_core/buffer_cache/buffer_cache.h
+++ b/src/video_core/buffer_cache/buffer_cache.h
@@ -586,7 +586,9 @@ void BufferCache<P>::CommitAsyncFlushesHigh() {
586 cpu_addr_base += u64(std::max<s64>(difference2, 0)); 586 cpu_addr_base += u64(std::max<s64>(difference2, 0));
587 const u64 new_size = cpu_addr_end2 - cpu_addr_base; 587 const u64 new_size = cpu_addr_end2 - cpu_addr_base;
588 const u64 new_offset = cpu_addr_base - buffer.CpuAddr(); 588 const u64 new_offset = cpu_addr_base - buffer.CpuAddr();
589 ASSERT(!IsRegionCpuModified(cpu_addr_base, new_size)); 589 if (IsRegionCpuModified(cpu_addr_base, new_size)) {
590 return;
591 }
590 downloads.push_back({ 592 downloads.push_back({
591 BufferCopy{ 593 BufferCopy{
592 .src_offset = new_offset, 594 .src_offset = new_offset,
@@ -596,8 +598,15 @@ void BufferCache<P>::CommitAsyncFlushesHigh() {
596 buffer_id, 598 buffer_id,
597 }); 599 });
598 total_size_bytes += new_size; 600 total_size_bytes += new_size;
599 buffer.UnmarkRegionAsGpuModified(cpu_addr_base, new_size);
600 largest_copy = std::max(largest_copy, new_size); 601 largest_copy = std::max(largest_copy, new_size);
602 constexpr u64 align_mask = ~(32ULL - 1);
603 const VAddr align_up_address = (cpu_addr_base + 31) & align_mask;
604 const u64 difference = align_up_address - cpu_addr_base;
605 if (difference > new_size) {
606 return;
607 }
608 const u64 fixed_size = new_size - difference;
609 buffer.UnmarkRegionAsGpuModified(align_up_address, fixed_size & align_mask);
601 }); 610 });
602 }); 611 });
603 } 612 }
@@ -1380,7 +1389,8 @@ typename BufferCache<P>::Binding BufferCache<P>::StorageBufferBinding(GPUVAddr s
1380 // Binding the whole map range would be technically correct, but games have large maps that make 1389 // Binding the whole map range would be technically correct, but games have large maps that make
1381 // this approach unaffordable for now. 1390 // this approach unaffordable for now.
1382 static constexpr u32 arbitrary_extra_bytes = 0xc000; 1391 static constexpr u32 arbitrary_extra_bytes = 0xc000;
1383 const u32 bytes_to_map_end = static_cast<u32>(gpu_memory.BytesToMapEnd(gpu_addr)); 1392 const u32 bytes_to_map_end =
1393 std::max(size, static_cast<u32>(gpu_memory.BytesToMapEnd(gpu_addr)));
1384 const Binding binding{ 1394 const Binding binding{
1385 .cpu_addr = *cpu_addr, 1395 .cpu_addr = *cpu_addr,
1386 .size = std::min(size + arbitrary_extra_bytes, bytes_to_map_end), 1396 .size = std::min(size + arbitrary_extra_bytes, bytes_to_map_end),
diff --git a/src/video_core/fence_manager.h b/src/video_core/fence_manager.h
index f055b61e9..cd17667cb 100644
--- a/src/video_core/fence_manager.h
+++ b/src/video_core/fence_manager.h
@@ -8,6 +8,7 @@
8#include <queue> 8#include <queue>
9 9
10#include "common/common_types.h" 10#include "common/common_types.h"
11#include "common/settings.h"
11#include "core/core.h" 12#include "core/core.h"
12#include "video_core/delayed_destruction_ring.h" 13#include "video_core/delayed_destruction_ring.h"
13#include "video_core/gpu.h" 14#include "video_core/gpu.h"
@@ -53,6 +54,23 @@ public:
53 delayed_destruction_ring.Tick(); 54 delayed_destruction_ring.Tick();
54 } 55 }
55 56
57 void SignalReference() {
58 // Only sync references on High
59 if (Settings::values.gpu_accuracy.GetValue() != Settings::GPUAccuracy::High) {
60 return;
61 }
62 TryReleasePendingFences();
63 const bool should_flush = ShouldFlush();
64 CommitAsyncFlushes();
65 TFence new_fence = CreateFence(0, 0, !should_flush);
66 fences.push(new_fence);
67 QueueFence(new_fence);
68 if (should_flush) {
69 rasterizer.FlushCommands();
70 }
71 rasterizer.SyncGuestHost();
72 }
73
56 void SignalSemaphore(GPUVAddr addr, u32 value) { 74 void SignalSemaphore(GPUVAddr addr, u32 value) {
57 TryReleasePendingFences(); 75 TryReleasePendingFences();
58 const bool should_flush = ShouldFlush(); 76 const bool should_flush = ShouldFlush();
@@ -87,8 +105,10 @@ public:
87 } 105 }
88 PopAsyncFlushes(); 106 PopAsyncFlushes();
89 if (current_fence->IsSemaphore()) { 107 if (current_fence->IsSemaphore()) {
90 gpu_memory.template Write<u32>(current_fence->GetAddress(), 108 if (current_fence->GetAddress() != 0) {
91 current_fence->GetPayload()); 109 gpu_memory.template Write<u32>(current_fence->GetAddress(),
110 current_fence->GetPayload());
111 }
92 } else { 112 } else {
93 gpu.IncrementSyncPoint(current_fence->GetPayload()); 113 gpu.IncrementSyncPoint(current_fence->GetPayload());
94 } 114 }
diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp
index 35cc561be..f317ddc2b 100644
--- a/src/video_core/gpu.cpp
+++ b/src/video_core/gpu.cpp
@@ -268,11 +268,13 @@ void GPU::CallPullerMethod(const MethodCall& method_call) {
268 case BufferMethods::SemaphoreAddressHigh: 268 case BufferMethods::SemaphoreAddressHigh:
269 case BufferMethods::SemaphoreAddressLow: 269 case BufferMethods::SemaphoreAddressLow:
270 case BufferMethods::SemaphoreSequence: 270 case BufferMethods::SemaphoreSequence:
271 case BufferMethods::RefCnt:
272 case BufferMethods::UnkCacheFlush: 271 case BufferMethods::UnkCacheFlush:
273 case BufferMethods::WrcacheFlush: 272 case BufferMethods::WrcacheFlush:
274 case BufferMethods::FenceValue: 273 case BufferMethods::FenceValue:
275 break; 274 break;
275 case BufferMethods::RefCnt:
276 rasterizer->SignalReference();
277 break;
276 case BufferMethods::FenceAction: 278 case BufferMethods::FenceAction:
277 ProcessFenceActionMethod(); 279 ProcessFenceActionMethod();
278 break; 280 break;
diff --git a/src/video_core/rasterizer_interface.h b/src/video_core/rasterizer_interface.h
index 0cec4225b..67aef6000 100644
--- a/src/video_core/rasterizer_interface.h
+++ b/src/video_core/rasterizer_interface.h
@@ -63,6 +63,9 @@ public:
63 /// Signal a GPU based syncpoint as a fence 63 /// Signal a GPU based syncpoint as a fence
64 virtual void SignalSyncPoint(u32 value) = 0; 64 virtual void SignalSyncPoint(u32 value) = 0;
65 65
66 /// Signal a GPU based reference as point
67 virtual void SignalReference() = 0;
68
66 /// Release all pending fences. 69 /// Release all pending fences.
67 virtual void ReleaseFences() = 0; 70 virtual void ReleaseFences() = 0;
68 71
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 07ad0e205..64869abf9 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -634,6 +634,13 @@ void RasterizerOpenGL::SignalSyncPoint(u32 value) {
634 fence_manager.SignalSyncPoint(value); 634 fence_manager.SignalSyncPoint(value);
635} 635}
636 636
637void RasterizerOpenGL::SignalReference() {
638 if (!gpu.IsAsync()) {
639 return;
640 }
641 fence_manager.SignalReference();
642}
643
637void RasterizerOpenGL::ReleaseFences() { 644void RasterizerOpenGL::ReleaseFences() {
638 if (!gpu.IsAsync()) { 645 if (!gpu.IsAsync()) {
639 return; 646 return;
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index 482efed7a..d8df71962 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -83,6 +83,7 @@ public:
83 void ModifyGPUMemory(GPUVAddr addr, u64 size) override; 83 void ModifyGPUMemory(GPUVAddr addr, u64 size) override;
84 void SignalSemaphore(GPUVAddr addr, u32 value) override; 84 void SignalSemaphore(GPUVAddr addr, u32 value) override;
85 void SignalSyncPoint(u32 value) override; 85 void SignalSyncPoint(u32 value) override;
86 void SignalReference() override;
86 void ReleaseFences() override; 87 void ReleaseFences() override;
87 void FlushAndInvalidateRegion(VAddr addr, u64 size) override; 88 void FlushAndInvalidateRegion(VAddr addr, u64 size) override;
88 void WaitForIdle() override; 89 void WaitForIdle() override;
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
index bd4d649cc..687c13009 100644
--- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp
+++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
@@ -580,6 +580,13 @@ void RasterizerVulkan::SignalSyncPoint(u32 value) {
580 fence_manager.SignalSyncPoint(value); 580 fence_manager.SignalSyncPoint(value);
581} 581}
582 582
583void RasterizerVulkan::SignalReference() {
584 if (!gpu.IsAsync()) {
585 return;
586 }
587 fence_manager.SignalReference();
588}
589
583void RasterizerVulkan::ReleaseFences() { 590void RasterizerVulkan::ReleaseFences() {
584 if (!gpu.IsAsync()) { 591 if (!gpu.IsAsync()) {
585 return; 592 return;
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.h b/src/video_core/renderer_vulkan/vk_rasterizer.h
index 41459c5c5..5450ccfb5 100644
--- a/src/video_core/renderer_vulkan/vk_rasterizer.h
+++ b/src/video_core/renderer_vulkan/vk_rasterizer.h
@@ -75,6 +75,7 @@ public:
75 void ModifyGPUMemory(GPUVAddr addr, u64 size) override; 75 void ModifyGPUMemory(GPUVAddr addr, u64 size) override;
76 void SignalSemaphore(GPUVAddr addr, u32 value) override; 76 void SignalSemaphore(GPUVAddr addr, u32 value) override;
77 void SignalSyncPoint(u32 value) override; 77 void SignalSyncPoint(u32 value) override;
78 void SignalReference() override;
78 void ReleaseFences() override; 79 void ReleaseFences() override;
79 void FlushAndInvalidateRegion(VAddr addr, u64 size) override; 80 void FlushAndInvalidateRegion(VAddr addr, u64 size) override;
80 void WaitForIdle() override; 81 void WaitForIdle() override;