summaryrefslogtreecommitdiff
path: root/src/core/hle
diff options
context:
space:
mode:
authorFernando Sahmkow <fsahmkow27@gmail.com>2019-09-25 19:43:23 -0400
committerFernandoS27 <fsahmkow27@gmail.com>2019-10-04 19:59:48 -0400
commit5b5e60ffeca1a718cd980e74f0528d6ab91788cf (patch)
tree56073a1d11122b8253a69f8e908f6f44687cc3d3 /src/core/hle
parent4e9f975935b4208b29e158dabe62f8ad1122a447 (diff)
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/hle')
-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) {
displays.emplace_back(3, "Internal", system);
displays.emplace_back(4, "Null", system);
+ for (auto& display : displays) {
+ display.SignalVSyncEvent();
+ }
+
// Schedule the screen composition events
composition_event = system.CoreTiming().RegisterEvent(
"ScreenComposition", [this](u64 userdata, s64 cycles_late) {
@@ -173,7 +177,13 @@ void NVFlinger::Compose() {
bool trigger_event = false;
// Trigger vsync for this display at the end of drawing
SCOPE_EXIT({
- if (trigger_event) {
+ // TODO(Blinkhawk): Correctly send buffers through nvflinger while
+ // loading the game thorugh the OS.
+ // During loading, the OS takes care of sending buffers to vsync,
+ // thus it triggers, since this is not properly emulated due to
+ // HLE complications, we allow it to signal until the game enqueues
+ // it's first buffer.
+ if (trigger_event || !first_buffer_enqueued) {
display.SignalVSyncEvent();
}
});
@@ -193,13 +203,20 @@ void NVFlinger::Compose() {
if (!buffer) {
// There was no queued buffer to draw, render previous frame
- system.GetPerfStats().EndGameFrame();
system.GPU().SwapBuffers({});
continue;
}
const auto& igbp_buffer = buffer->get().igbp_buffer;
trigger_event = true;
+ first_buffer_enqueued = true;
+
+ const auto& gpu = system.GPU();
+ const auto& multi_fence = buffer->get().multi_fence;
+ for (u32 fence_id = 0; fence_id < multi_fence.num_fences; fence_id++) {
+ const auto& fence = multi_fence.fences[fence_id];
+ gpu.WaitFence(fence.id, fence.value);
+ }
// Now send the buffer to the GPU for drawing.
// 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:
u32 swap_interval = 1;
+ bool first_buffer_enqueued{};
+
/// Event that handles screen composition.
Core::Timing::EventType* composition_event;