summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorGravatar Fernando Sahmkow2019-09-25 19:43:23 -0400
committerGravatar FernandoS272019-10-04 19:59:48 -0400
commit5b5e60ffeca1a718cd980e74f0528d6ab91788cf (patch)
tree56073a1d11122b8253a69f8e908f6f44687cc3d3 /src/core
parentNvdrv: Correct Async regression and avoid signaling empty buffer vsyncs (diff)
downloadyuzu-5b5e60ffeca1a718cd980e74f0528d6ab91788cf.tar.gz
yuzu-5b5e60ffeca1a718cd980e74f0528d6ab91788cf.tar.xz
yuzu-5b5e60ffeca1a718cd980e74f0528d6ab91788cf.zip
GPU_Async: Correct fences, display events and more.
This commit uses guest fences on vSync event instead of an articial fake fence we had. It also corrects to keep signaling display events while loading the game as the OS is suppose to send buffers to vSync during that time.
Diffstat (limited to 'src/core')
-rw-r--r--src/core/hle/service/nvflinger/nvflinger.cpp21
-rw-r--r--src/core/hle/service/nvflinger/nvflinger.h2
2 files changed, 21 insertions, 2 deletions
diff --git a/src/core/hle/service/nvflinger/nvflinger.cpp b/src/core/hle/service/nvflinger/nvflinger.cpp
index 3b251f8c8..86a90526c 100644
--- a/src/core/hle/service/nvflinger/nvflinger.cpp
+++ b/src/core/hle/service/nvflinger/nvflinger.cpp
@@ -36,6 +36,10 @@ NVFlinger::NVFlinger(Core::System& system) : system(system) {
36 displays.emplace_back(3, "Internal", system); 36 displays.emplace_back(3, "Internal", system);
37 displays.emplace_back(4, "Null", system); 37 displays.emplace_back(4, "Null", system);
38 38
39 for (auto& display : displays) {
40 display.SignalVSyncEvent();
41 }
42
39 // Schedule the screen composition events 43 // Schedule the screen composition events
40 composition_event = system.CoreTiming().RegisterEvent( 44 composition_event = system.CoreTiming().RegisterEvent(
41 "ScreenComposition", [this](u64 userdata, s64 cycles_late) { 45 "ScreenComposition", [this](u64 userdata, s64 cycles_late) {
@@ -173,7 +177,13 @@ void NVFlinger::Compose() {
173 bool trigger_event = false; 177 bool trigger_event = false;
174 // Trigger vsync for this display at the end of drawing 178 // Trigger vsync for this display at the end of drawing
175 SCOPE_EXIT({ 179 SCOPE_EXIT({
176 if (trigger_event) { 180 // TODO(Blinkhawk): Correctly send buffers through nvflinger while
181 // loading the game thorugh the OS.
182 // During loading, the OS takes care of sending buffers to vsync,
183 // thus it triggers, since this is not properly emulated due to
184 // HLE complications, we allow it to signal until the game enqueues
185 // it's first buffer.
186 if (trigger_event || !first_buffer_enqueued) {
177 display.SignalVSyncEvent(); 187 display.SignalVSyncEvent();
178 } 188 }
179 }); 189 });
@@ -193,13 +203,20 @@ void NVFlinger::Compose() {
193 203
194 if (!buffer) { 204 if (!buffer) {
195 // There was no queued buffer to draw, render previous frame 205 // There was no queued buffer to draw, render previous frame
196 system.GetPerfStats().EndGameFrame();
197 system.GPU().SwapBuffers({}); 206 system.GPU().SwapBuffers({});
198 continue; 207 continue;
199 } 208 }
200 209
201 const auto& igbp_buffer = buffer->get().igbp_buffer; 210 const auto& igbp_buffer = buffer->get().igbp_buffer;
202 trigger_event = true; 211 trigger_event = true;
212 first_buffer_enqueued = true;
213
214 const auto& gpu = system.GPU();
215 const auto& multi_fence = buffer->get().multi_fence;
216 for (u32 fence_id = 0; fence_id < multi_fence.num_fences; fence_id++) {
217 const auto& fence = multi_fence.fences[fence_id];
218 gpu.WaitFence(fence.id, fence.value);
219 }
203 220
204 // Now send the buffer to the GPU for drawing. 221 // Now send the buffer to the GPU for drawing.
205 // TODO(Subv): Support more than just disp0. The display device selection is probably based 222 // TODO(Subv): Support more than just disp0. The display device selection is probably based
diff --git a/src/core/hle/service/nvflinger/nvflinger.h b/src/core/hle/service/nvflinger/nvflinger.h
index 5d7e3bfb8..95d7278f5 100644
--- a/src/core/hle/service/nvflinger/nvflinger.h
+++ b/src/core/hle/service/nvflinger/nvflinger.h
@@ -102,6 +102,8 @@ private:
102 102
103 u32 swap_interval = 1; 103 u32 swap_interval = 1;
104 104
105 bool first_buffer_enqueued{};
106
105 /// Event that handles screen composition. 107 /// Event that handles screen composition.
106 Core::Timing::EventType* composition_event; 108 Core::Timing::EventType* composition_event;
107 109