summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorGravatar Fernando Sahmkow2021-10-30 11:35:05 +0200
committerGravatar Fernando Sahmkow2022-10-06 21:00:51 +0200
commitac104a24d11c5875e25daee5dd405ee9fe5f3a21 (patch)
treee25f2ebf312e60536573bf33ca1d72c982e359bb /src/core
parentNvHost: Fix some regressions and correct signaling on timeout. (diff)
downloadyuzu-ac104a24d11c5875e25daee5dd405ee9fe5f3a21.tar.gz
yuzu-ac104a24d11c5875e25daee5dd405ee9fe5f3a21.tar.xz
yuzu-ac104a24d11c5875e25daee5dd405ee9fe5f3a21.zip
NvHost: Try a different approach to blocking.
Diffstat (limited to 'src/core')
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp15
-rw-r--r--src/core/hle/service/nvdrv/nvdrv.h2
2 files changed, 7 insertions, 10 deletions
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
index a3c11ad8a..bfe1faf48 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
@@ -91,7 +91,7 @@ NvResult nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector
91 if (syncpoint_manager.IsSyncpointExpired(params.syncpt_id, params.threshold)) { 91 if (syncpoint_manager.IsSyncpointExpired(params.syncpt_id, params.threshold)) {
92 params.value = syncpoint_manager.GetSyncpointMin(params.syncpt_id); 92 params.value = syncpoint_manager.GetSyncpointMin(params.syncpt_id);
93 std::memcpy(output.data(), &params, sizeof(params)); 93 std::memcpy(output.data(), &params, sizeof(params));
94 events_interface.failed[event_id] = false; 94 events_interface.fails[event_id] = 0;
95 return NvResult::Success; 95 return NvResult::Success;
96 } 96 }
97 97
@@ -99,29 +99,26 @@ NvResult nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector
99 syncpoint_manager.IsSyncpointExpired(params.syncpt_id, params.threshold)) { 99 syncpoint_manager.IsSyncpointExpired(params.syncpt_id, params.threshold)) {
100 params.value = new_value; 100 params.value = new_value;
101 std::memcpy(output.data(), &params, sizeof(params)); 101 std::memcpy(output.data(), &params, sizeof(params));
102 events_interface.failed[event_id] = false; 102 events_interface.fails[event_id] = 0;
103 return NvResult::Success; 103 return NvResult::Success;
104 } 104 }
105 105
106 auto& event = events_interface.events[event_id];
107 auto& gpu = system.GPU(); 106 auto& gpu = system.GPU();
108 const u32 current_syncpoint_value = event.fence.value; 107 const u32 target_value = syncpoint_manager.GetSyncpointMax(params.syncpt_id);
109 const s32 diff = current_syncpoint_value - params.threshold;
110 const u32 target_value = params.value;
111 108
112 if (!is_async) { 109 if (!is_async) {
113 params.value = 0; 110 params.value = 0;
114 } 111 }
115 112
116 const auto check_failing = [&]() { 113 const auto check_failing = [&]() {
117 if (events_interface.failed[event_id]) { 114 if (events_interface.fails[event_id] > 1) {
118 { 115 {
119 auto lk = system.StallProcesses(); 116 auto lk = system.StallProcesses();
120 gpu.WaitFence(params.syncpt_id, target_value); 117 gpu.WaitFence(params.syncpt_id, target_value);
121 system.UnstallProcesses(); 118 system.UnstallProcesses();
122 } 119 }
123 std::memcpy(output.data(), &params, sizeof(params)); 120 std::memcpy(output.data(), &params, sizeof(params));
124 events_interface.failed[event_id] = false; 121 events_interface.fails[event_id] = 0;
125 return true; 122 return true;
126 } 123 }
127 return false; 124 return false;
@@ -207,7 +204,7 @@ NvResult nvhost_ctrl::IocCtrlClearEventWait(const std::vector<u8>& input, std::v
207 if (events_interface.status[event_id] == EventState::Waiting) { 204 if (events_interface.status[event_id] == EventState::Waiting) {
208 events_interface.LiberateEvent(event_id); 205 events_interface.LiberateEvent(event_id);
209 } 206 }
210 events_interface.failed[event_id] = true; 207 events_interface.fails[event_id]++;
211 208
212 syncpoint_manager.RefreshSyncpoint(events_interface.events[event_id].fence.id); 209 syncpoint_manager.RefreshSyncpoint(events_interface.events[event_id].fence.id);
213 210
diff --git a/src/core/hle/service/nvdrv/nvdrv.h b/src/core/hle/service/nvdrv/nvdrv.h
index c929e5106..4c4aa7dab 100644
--- a/src/core/hle/service/nvdrv/nvdrv.h
+++ b/src/core/hle/service/nvdrv/nvdrv.h
@@ -50,7 +50,7 @@ struct EventInterface {
50 // Tells if an NVEvent is registered or not 50 // Tells if an NVEvent is registered or not
51 std::array<bool, MaxNvEvents> registered{}; 51 std::array<bool, MaxNvEvents> registered{};
52 // Tells the NVEvent that it has failed. 52 // Tells the NVEvent that it has failed.
53 std::array<bool, MaxNvEvents> failed{}; 53 std::array<u32, MaxNvEvents> fails{};
54 // When an NVEvent is waiting on GPU interrupt, this is the sync_point 54 // When an NVEvent is waiting on GPU interrupt, this is the sync_point
55 // associated with it. 55 // associated with it.
56 std::array<u32, MaxNvEvents> assigned_syncpt{}; 56 std::array<u32, MaxNvEvents> assigned_syncpt{};