diff options
| author | 2019-06-07 21:13:20 -0400 | |
|---|---|---|
| committer | 2019-07-05 15:49:15 -0400 | |
| commit | a45643cb3b07e76e73814baf1d472d636dd2cd91 (patch) | |
| tree | 8cea1037fcfdaa473f8362686ff2d46ee10745d5 | |
| parent | Gpu: Implement Hardware Interrupt Manager and manage GPU interrupts (diff) | |
| download | yuzu-a45643cb3b07e76e73814baf1d472d636dd2cd91.tar.gz yuzu-a45643cb3b07e76e73814baf1d472d636dd2cd91.tar.xz yuzu-a45643cb3b07e76e73814baf1d472d636dd2cd91.zip | |
nv_services: Stub CtrlEventSignal
| -rw-r--r-- | src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp | 44 | ||||
| -rw-r--r-- | src/core/hle/service/nvdrv/devices/nvhost_ctrl.h | 2 | ||||
| -rw-r--r-- | src/video_core/gpu.cpp | 11 | ||||
| -rw-r--r-- | src/video_core/gpu.h | 4 |
4 files changed, 48 insertions, 13 deletions
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp index ef6731a8f..8f47d63e3 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp | |||
| @@ -33,6 +33,8 @@ u32 nvhost_ctrl::ioctl(Ioctl command, const std::vector<u8>& input, std::vector< | |||
| 33 | return IocCtrlEventRegister(input, output); | 33 | return IocCtrlEventRegister(input, output); |
| 34 | case IoctlCommand::IocCtrlEventUnregisterCommand: | 34 | case IoctlCommand::IocCtrlEventUnregisterCommand: |
| 35 | return IocCtrlEventUnregister(input, output); | 35 | return IocCtrlEventUnregister(input, output); |
| 36 | case IoctlCommand::IocCtrlEventSignalCommand: | ||
| 37 | return IocCtrlEventSignal(input, output); | ||
| 36 | } | 38 | } |
| 37 | UNIMPLEMENTED_MSG("Unimplemented ioctl"); | 39 | UNIMPLEMENTED_MSG("Unimplemented ioctl"); |
| 38 | return 0; | 40 | return 0; |
| @@ -74,30 +76,29 @@ u32 nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector<u8>& | |||
| 74 | return NvResult::Timeout; | 76 | return NvResult::Timeout; |
| 75 | } | 77 | } |
| 76 | 78 | ||
| 77 | u32 event_index; | 79 | u32 event_id; |
| 78 | if (is_async) { | 80 | if (is_async) { |
| 79 | event_index = params.value; | 81 | event_id = params.value & 0x00FF; |
| 80 | if (event_index >= 64) { | 82 | if (event_id >= 64) { |
| 81 | std::memcpy(output.data(), ¶ms, sizeof(params)); | 83 | std::memcpy(output.data(), ¶ms, sizeof(params)); |
| 82 | return NvResult::BadParameter; | 84 | return NvResult::BadParameter; |
| 83 | } | 85 | } |
| 84 | } else { | 86 | } else { |
| 85 | event_index = events_interface.GetFreeEvent(); | 87 | event_id = events_interface.GetFreeEvent(); |
| 86 | } | 88 | } |
| 87 | 89 | ||
| 88 | EventState status = events_interface.status[event_index]; | 90 | EventState status = events_interface.status[event_id]; |
| 89 | if (event_index < MaxNvEvents || status == EventState::Free || | 91 | if (event_id < MaxNvEvents || status == EventState::Free || status == EventState::Registered) { |
| 90 | status == EventState::Registered) { | 92 | events_interface.SetEventStatus(event_id, EventState::Waiting); |
| 91 | events_interface.SetEventStatus(event_index, EventState::Waiting); | 93 | events_interface.assigned_syncpt[event_id] = params.syncpt_id; |
| 92 | events_interface.assigned_syncpt[event_index] = params.syncpt_id; | 94 | events_interface.assigned_value[event_id] = params.threshold; |
| 93 | events_interface.assigned_value[event_index] = params.threshold; | ||
| 94 | if (is_async) { | 95 | if (is_async) { |
| 95 | params.value = params.syncpt_id << 4; | 96 | params.value = params.syncpt_id << 4; |
| 96 | } else { | 97 | } else { |
| 97 | params.value = ((params.syncpt_id & 0xfff) << 16) | 0x10000000; | 98 | params.value = ((params.syncpt_id & 0xfff) << 16) | 0x10000000; |
| 98 | } | 99 | } |
| 99 | params.value |= event_index; | 100 | params.value |= event_id; |
| 100 | gpu.RegisterEvent(event_index, params.syncpt_id, params.threshold); | 101 | gpu.RegisterEvent(event_id, params.syncpt_id, params.threshold); |
| 101 | std::memcpy(output.data(), ¶ms, sizeof(params)); | 102 | std::memcpy(output.data(), ¶ms, sizeof(params)); |
| 102 | return NvResult::Timeout; | 103 | return NvResult::Timeout; |
| 103 | } | 104 | } |
| @@ -131,4 +132,23 @@ u32 nvhost_ctrl::IocCtrlEventUnregister(const std::vector<u8>& input, std::vecto | |||
| 131 | return NvResult::Success; | 132 | return NvResult::Success; |
| 132 | } | 133 | } |
| 133 | 134 | ||
| 135 | u32 nvhost_ctrl::IocCtrlEventSignal(const std::vector<u8>& input, std::vector<u8>& output) { | ||
| 136 | IocCtrlEventSignalParams params{}; | ||
| 137 | std::memcpy(¶ms, input.data(), sizeof(params)); | ||
| 138 | // TODO(Blinkhawk): This is normally called when an NvEvents timeout on WaitSynchronization | ||
| 139 | // It is believed to cancel the GPU Event. However, better research is required | ||
| 140 | u32 event_id = params.user_event_id & 0x00FF; | ||
| 141 | LOG_WARNING(Service_NVDRV, "(STUBBED) called, user_event_id: {:X}", event_id); | ||
| 142 | if (event_id >= MaxNvEvents) { | ||
| 143 | return NvResult::BadParameter; | ||
| 144 | } | ||
| 145 | if (events_interface.status[event_id] == EventState::Waiting) { | ||
| 146 | auto& gpu = Core::System::GetInstance().GPU(); | ||
| 147 | gpu.CancelEvent(event_id, events_interface.assigned_syncpt[event_id], | ||
| 148 | events_interface.assigned_value[event_id]); | ||
| 149 | events_interface.LiberateEvent(event_id); | ||
| 150 | } | ||
| 151 | return NvResult::Success; | ||
| 152 | } | ||
| 153 | |||
| 134 | } // namespace Service::Nvidia::Devices | 154 | } // namespace Service::Nvidia::Devices |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h index 2985e7f75..b5bc9337b 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h | |||
| @@ -139,6 +139,8 @@ private: | |||
| 139 | 139 | ||
| 140 | u32 IocCtrlEventUnregister(const std::vector<u8>& input, std::vector<u8>& output); | 140 | u32 IocCtrlEventUnregister(const std::vector<u8>& input, std::vector<u8>& output); |
| 141 | 141 | ||
| 142 | u32 IocCtrlEventSignal(const std::vector<u8>& input, std::vector<u8>& output); | ||
| 143 | |||
| 142 | EventsInterface& events_interface; | 144 | EventsInterface& events_interface; |
| 143 | }; | 145 | }; |
| 144 | 146 | ||
diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp index 06eb570ab..1fa6770ca 100644 --- a/src/video_core/gpu.cpp +++ b/src/video_core/gpu.cpp | |||
| @@ -95,6 +95,17 @@ void GPU::RegisterEvent(const u32 event_id, const u32 syncpoint_id, const u32 va | |||
| 95 | events[syncpoint_id].emplace_back(event_id, value); | 95 | events[syncpoint_id].emplace_back(event_id, value); |
| 96 | } | 96 | } |
| 97 | 97 | ||
| 98 | void GPU::CancelEvent(const u32 event_id, const u32 syncpoint_id, const u32 value) { | ||
| 99 | auto it = events[syncpoint_id].begin(); | ||
| 100 | while (it != events[syncpoint_id].end()) { | ||
| 101 | if (value == it->value) { | ||
| 102 | it = events[syncpoint_id].erase(it); | ||
| 103 | return; | ||
| 104 | } | ||
| 105 | it++; | ||
| 106 | } | ||
| 107 | } | ||
| 108 | |||
| 98 | u32 RenderTargetBytesPerPixel(RenderTargetFormat format) { | 109 | u32 RenderTargetBytesPerPixel(RenderTargetFormat format) { |
| 99 | ASSERT(format != RenderTargetFormat::NONE); | 110 | ASSERT(format != RenderTargetFormat::NONE); |
| 100 | 111 | ||
diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h index c3e5311fa..4805a5fbc 100644 --- a/src/video_core/gpu.h +++ b/src/video_core/gpu.h | |||
| @@ -171,7 +171,9 @@ public: | |||
| 171 | 171 | ||
| 172 | u32 GetSyncpointValue(const u32 syncpoint_id) const; | 172 | u32 GetSyncpointValue(const u32 syncpoint_id) const; |
| 173 | 173 | ||
| 174 | void RegisterEvent(const u32 event_id, const u32 sync_point_id, const u32 value); | 174 | void RegisterEvent(const u32 event_id, const u32 syncpoint_id, const u32 value); |
| 175 | |||
| 176 | void CancelEvent(const u32 event_id, const u32 syncpoint_id, const u32 value); | ||
| 175 | 177 | ||
| 176 | /// Returns a const reference to the GPU DMA pusher. | 178 | /// Returns a const reference to the GPU DMA pusher. |
| 177 | const Tegra::DmaPusher& DmaPusher() const; | 179 | const Tegra::DmaPusher& DmaPusher() const; |