From 0335a25d1fcca5328ef79b3c62edb679df63ffba Mon Sep 17 00:00:00 2001
From: Fernando Sahmkow <fsahmkow27@gmail.com>
Date: Mon, 17 Jun 2019 15:27:42 -0400
Subject: [PATCH] NVServices: Make NVEvents Automatic according to
 documentation.

---
 src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp | 7 +++++--
 src/core/hle/service/nvdrv/nvdrv.cpp               | 4 ++--
 src/video_core/gpu.cpp                             | 7 +++++--
 src/video_core/gpu.h                               | 2 +-
 4 files changed, 13 insertions(+), 7 deletions(-)

diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
index e46e6b94c..ffa6e75c7 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
@@ -142,7 +142,6 @@ u32 nvhost_ctrl::IocCtrlEventRegister(const std::vector<u8>& input, std::vector<
         return NvResult::BadParameter;
     }
     events_interface.RegisterEvent(event_id);
-    events_interface.events[event_id].writable->Signal();
     return NvResult::Success;
 }
 
@@ -171,7 +170,11 @@ u32 nvhost_ctrl::IocCtrlEventSignal(const std::vector<u8>& input, std::vector<u8
         return NvResult::BadParameter;
     }
     if (events_interface.status[event_id] == EventState::Waiting) {
-        events_interface.LiberateEvent(event_id);
+        auto& gpu = system.GPU();
+        if (gpu.CancelSyncptInterrupt(events_interface.assigned_syncpt[event_id],
+                                      events_interface.assigned_value[event_id])) {
+            events_interface.LiberateEvent(event_id);
+        }
     }
     return NvResult::Success;
 }
diff --git a/src/core/hle/service/nvdrv/nvdrv.cpp b/src/core/hle/service/nvdrv/nvdrv.cpp
index 598a1123b..8958e21e3 100644
--- a/src/core/hle/service/nvdrv/nvdrv.cpp
+++ b/src/core/hle/service/nvdrv/nvdrv.cpp
@@ -40,8 +40,8 @@ Module::Module(Core::System& system) {
     auto& kernel = system.Kernel();
     for (u32 i = 0; i < MaxNvEvents; i++) {
         std::string event_label = fmt::format("NVDRV::NvEvent_{}", i);
-        events_interface.events[i] =
-            Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Manual, event_label);
+        events_interface.events[i] = Kernel::WritableEvent::CreateEventPair(
+            kernel, Kernel::ResetType::Automatic, event_label);
         events_interface.status[i] = EventState::Free;
         events_interface.registered[i] = false;
     }
diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp
index efea23bf2..cdb2f804e 100644
--- a/src/video_core/gpu.cpp
+++ b/src/video_core/gpu.cpp
@@ -97,15 +97,18 @@ void GPU::RegisterSyncptInterrupt(const u32 syncpoint_id, const u32 value) {
     syncpt_interrupts[syncpoint_id].emplace_back(value);
 }
 
-void GPU::CancelSyncptInterrupt(const u32 syncpoint_id, const u32 value) {
+bool GPU::CancelSyncptInterrupt(const u32 syncpoint_id, const u32 value) {
+    sync_mutex.lock();
     auto it = syncpt_interrupts[syncpoint_id].begin();
     while (it != syncpt_interrupts[syncpoint_id].end()) {
         if (value == *it) {
             it = syncpt_interrupts[syncpoint_id].erase(it);
-            return;
+            return true;
         }
         it++;
     }
+    return false;
+    sync_mutex.unlock();
 }
 
 u32 RenderTargetBytesPerPixel(RenderTargetFormat format) {
diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h
index 9bd618941..94afc91f8 100644
--- a/src/video_core/gpu.h
+++ b/src/video_core/gpu.h
@@ -174,7 +174,7 @@ public:
 
     void RegisterSyncptInterrupt(const u32 syncpoint_id, const u32 value);
 
-    void CancelSyncptInterrupt(const u32 syncpoint_id, const u32 value);
+    bool CancelSyncptInterrupt(const u32 syncpoint_id, const u32 value);
 
     void Guard(bool guard_set) {
         if (guard_set) {