diff options
| author | 2021-11-07 14:17:32 +0100 | |
|---|---|---|
| committer | 2022-10-06 21:00:51 +0200 | |
| commit | 2c62563ab58a70236a39571149f8370f3fdfb2a3 (patch) | |
| tree | 02cfe114d95ca19d1b35cbdd659d8ca8f27fb501 /src | |
| parent | VideoCore: implement channels on gpu caches. (diff) | |
| download | yuzu-2c62563ab58a70236a39571149f8370f3fdfb2a3.tar.gz yuzu-2c62563ab58a70236a39571149f8370f3fdfb2a3.tar.xz yuzu-2c62563ab58a70236a39571149f8370f3fdfb2a3.zip | |
NVHOST_CTRl: Implement missing method and fix some stuffs.
Diffstat (limited to 'src')
| -rw-r--r-- | src/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp | 30 | ||||
| -rw-r--r-- | src/core/hle/service/nvdrv/devices/nvhost_ctrl.h | 5 | ||||
| -rw-r--r-- | src/video_core/gpu.cpp | 5 |
4 files changed, 35 insertions, 6 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 54de1dc94..3575a3cb3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt | |||
| @@ -121,6 +121,7 @@ else() | |||
| 121 | 121 | ||
| 122 | if (ARCHITECTURE_x86_64) | 122 | if (ARCHITECTURE_x86_64) |
| 123 | add_compile_options("-mcx16") | 123 | add_compile_options("-mcx16") |
| 124 | add_compile_options("-fwrapv") | ||
| 124 | endif() | 125 | endif() |
| 125 | 126 | ||
| 126 | if (APPLE AND CMAKE_CXX_COMPILER_ID STREQUAL Clang) | 127 | if (APPLE AND CMAKE_CXX_COMPILER_ID STREQUAL Clang) |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp index abde2a6d3..0e22d9273 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp | |||
| @@ -52,6 +52,8 @@ NvResult nvhost_ctrl::Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& | |||
| 52 | return IocCtrlEventRegister(input, output); | 52 | return IocCtrlEventRegister(input, output); |
| 53 | case 0x20: | 53 | case 0x20: |
| 54 | return IocCtrlEventUnregister(input, output); | 54 | return IocCtrlEventUnregister(input, output); |
| 55 | case 0x21: | ||
| 56 | return IocCtrlEventUnregisterBatch(input, output); | ||
| 55 | } | 57 | } |
| 56 | break; | 58 | break; |
| 57 | default: | 59 | default: |
| @@ -249,6 +251,25 @@ NvResult nvhost_ctrl::IocCtrlEventUnregister(const std::vector<u8>& input, | |||
| 249 | return FreeEvent(event_id); | 251 | return FreeEvent(event_id); |
| 250 | } | 252 | } |
| 251 | 253 | ||
| 254 | NvResult nvhost_ctrl::IocCtrlEventUnregisterBatch(const std::vector<u8>& input, | ||
| 255 | std::vector<u8>& output) { | ||
| 256 | IocCtrlEventUnregisterBatchParams params{}; | ||
| 257 | std::memcpy(¶ms, input.data(), sizeof(params)); | ||
| 258 | u64 event_mask = params.user_events; | ||
| 259 | LOG_DEBUG(Service_NVDRV, " called, event_mask: {:X}", event_mask); | ||
| 260 | |||
| 261 | auto lock = NvEventsLock(); | ||
| 262 | while (event_mask != 0) { | ||
| 263 | const u64 event_id = std::countr_zero(event_mask); | ||
| 264 | event_mask &= ~(1ULL << event_id); | ||
| 265 | const auto result = FreeEvent(static_cast<u32>(event_id)); | ||
| 266 | if (result != NvResult::Success) { | ||
| 267 | return result; | ||
| 268 | } | ||
| 269 | } | ||
| 270 | return NvResult::Success; | ||
| 271 | } | ||
| 272 | |||
| 252 | NvResult nvhost_ctrl::IocCtrlClearEventWait(const std::vector<u8>& input, std::vector<u8>& output) { | 273 | NvResult nvhost_ctrl::IocCtrlClearEventWait(const std::vector<u8>& input, std::vector<u8>& output) { |
| 253 | IocCtrlEventClearParams params{}; | 274 | IocCtrlEventClearParams params{}; |
| 254 | std::memcpy(¶ms, input.data(), sizeof(params)); | 275 | std::memcpy(¶ms, input.data(), sizeof(params)); |
| @@ -362,10 +383,11 @@ u32 nvhost_ctrl::FindFreeNvEvent(u32 syncpoint_id) { | |||
| 362 | } | 383 | } |
| 363 | 384 | ||
| 364 | void nvhost_ctrl::SignalNvEvent(u32 syncpoint_id, u32 value) { | 385 | void nvhost_ctrl::SignalNvEvent(u32 syncpoint_id, u32 value) { |
| 365 | const u32 max = MaxNvEvents - std::countl_zero(events_mask); | 386 | u64 signal_mask = events_mask; |
| 366 | const u32 min = std::countr_zero(events_mask); | 387 | while (signal_mask != 0) { |
| 367 | for (u32 i = min; i < max; i++) { | 388 | const u64 event_id = std::countr_zero(signal_mask); |
| 368 | auto& event = events[i]; | 389 | signal_mask &= ~(1ULL << event_id); |
| 390 | auto& event = events[event_id]; | ||
| 369 | if (event.assigned_syncpt != syncpoint_id || event.assigned_value != value) { | 391 | if (event.assigned_syncpt != syncpoint_id || event.assigned_value != value) { |
| 370 | continue; | 392 | continue; |
| 371 | } | 393 | } |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h index f2fc5d047..9bd10257b 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h | |||
| @@ -177,16 +177,17 @@ private: | |||
| 177 | static_assert(sizeof(IocCtrlEventUnregisterParams) == 4, | 177 | static_assert(sizeof(IocCtrlEventUnregisterParams) == 4, |
| 178 | "IocCtrlEventUnregisterParams is incorrect size"); | 178 | "IocCtrlEventUnregisterParams is incorrect size"); |
| 179 | 179 | ||
| 180 | struct IocCtrlEventKill { | 180 | struct IocCtrlEventUnregisterBatchParams { |
| 181 | u64_le user_events{}; | 181 | u64_le user_events{}; |
| 182 | }; | 182 | }; |
| 183 | static_assert(sizeof(IocCtrlEventKill) == 8, "IocCtrlEventKill is incorrect size"); | 183 | static_assert(sizeof(IocCtrlEventUnregisterBatchParams) == 8, "IocCtrlEventKill is incorrect size"); |
| 184 | 184 | ||
| 185 | NvResult NvOsGetConfigU32(const std::vector<u8>& input, std::vector<u8>& output); | 185 | NvResult NvOsGetConfigU32(const std::vector<u8>& input, std::vector<u8>& output); |
| 186 | NvResult IocCtrlEventWait(const std::vector<u8>& input, std::vector<u8>& output, | 186 | NvResult IocCtrlEventWait(const std::vector<u8>& input, std::vector<u8>& output, |
| 187 | bool is_allocation); | 187 | bool is_allocation); |
| 188 | NvResult IocCtrlEventRegister(const std::vector<u8>& input, std::vector<u8>& output); | 188 | NvResult IocCtrlEventRegister(const std::vector<u8>& input, std::vector<u8>& output); |
| 189 | NvResult IocCtrlEventUnregister(const std::vector<u8>& input, std::vector<u8>& output); | 189 | NvResult IocCtrlEventUnregister(const std::vector<u8>& input, std::vector<u8>& output); |
| 190 | NvResult IocCtrlEventUnregisterBatch(const std::vector<u8>& input, std::vector<u8>& output); | ||
| 190 | NvResult IocCtrlClearEventWait(const std::vector<u8>& input, std::vector<u8>& output); | 191 | NvResult IocCtrlClearEventWait(const std::vector<u8>& input, std::vector<u8>& output); |
| 191 | 192 | ||
| 192 | NvResult FreeEvent(u32 slot); | 193 | NvResult FreeEvent(u32 slot); |
diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp index 80a1c69e0..8c0ff0094 100644 --- a/src/video_core/gpu.cpp +++ b/src/video_core/gpu.cpp | |||
| @@ -249,6 +249,11 @@ struct GPU::Impl { | |||
| 249 | 249 | ||
| 250 | void RegisterSyncptInterrupt(u32 syncpoint_id, u32 value) { | 250 | void RegisterSyncptInterrupt(u32 syncpoint_id, u32 value) { |
| 251 | std::scoped_lock lock{sync_mutex}; | 251 | std::scoped_lock lock{sync_mutex}; |
| 252 | u32 current_value = syncpoints.at(syncpoint_id).load(); | ||
| 253 | if ((static_cast<s32>(current_value) - static_cast<s32>(value)) >= 0) { | ||
| 254 | TriggerCpuInterrupt(syncpoint_id, value); | ||
| 255 | return; | ||
| 256 | } | ||
| 252 | auto& interrupt = syncpt_interrupts.at(syncpoint_id); | 257 | auto& interrupt = syncpt_interrupts.at(syncpoint_id); |
| 253 | bool contains = std::any_of(interrupt.begin(), interrupt.end(), | 258 | bool contains = std::any_of(interrupt.begin(), interrupt.end(), |
| 254 | [value](u32 in_value) { return in_value == value; }); | 259 | [value](u32 in_value) { return in_value == value; }); |