|
|
@@ -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
|