summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Fernando Sahmkow2019-06-07 21:13:20 -0400
committerGravatar FernandoS272019-07-05 15:49:15 -0400
commita45643cb3b07e76e73814baf1d472d636dd2cd91 (patch)
tree8cea1037fcfdaa473f8362686ff2d46ee10745d5
parentGpu: Implement Hardware Interrupt Manager and manage GPU interrupts (diff)
downloadyuzu-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.cpp44
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_ctrl.h2
-rw-r--r--src/video_core/gpu.cpp11
-rw-r--r--src/video_core/gpu.h4
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(), &params, sizeof(params)); 83 std::memcpy(output.data(), &params, 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(), &params, sizeof(params)); 102 std::memcpy(output.data(), &params, 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
135u32 nvhost_ctrl::IocCtrlEventSignal(const std::vector<u8>& input, std::vector<u8>& output) {
136 IocCtrlEventSignalParams params{};
137 std::memcpy(&params, 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
98void 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
98u32 RenderTargetBytesPerPixel(RenderTargetFormat format) { 109u32 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;