diff options
| author | 2021-10-30 11:35:05 +0200 | |
|---|---|---|
| committer | 2022-10-06 21:00:51 +0200 | |
| commit | ac104a24d11c5875e25daee5dd405ee9fe5f3a21 (patch) | |
| tree | e25f2ebf312e60536573bf33ca1d72c982e359bb /src/core | |
| parent | NvHost: Fix some regressions and correct signaling on timeout. (diff) | |
| download | yuzu-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.cpp | 15 | ||||
| -rw-r--r-- | src/core/hle/service/nvdrv/nvdrv.h | 2 |
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(), ¶ms, sizeof(params)); | 93 | std::memcpy(output.data(), ¶ms, 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(), ¶ms, sizeof(params)); | 101 | std::memcpy(output.data(), ¶ms, 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(), ¶ms, sizeof(params)); | 120 | std::memcpy(output.data(), ¶ms, 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{}; |