summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/hardware_interrupt_manager.cpp11
-rw-r--r--src/core/hardware_interrupt_manager.h2
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp5
-rw-r--r--src/core/hle/service/nvdrv/interface.cpp4
-rw-r--r--src/core/hle/service/nvdrv/interface.h2
-rw-r--r--src/core/hle/service/nvdrv/nvdrv.cpp13
-rw-r--r--src/core/hle/service/nvdrv/nvdrv.h4
-rw-r--r--src/video_core/gpu.cpp30
-rw-r--r--src/video_core/gpu.h14
-rw-r--r--src/video_core/gpu_asynch.cpp4
-rw-r--r--src/video_core/gpu_asynch.h2
-rw-r--r--src/video_core/gpu_synch.h2
12 files changed, 45 insertions, 48 deletions
diff --git a/src/core/hardware_interrupt_manager.cpp b/src/core/hardware_interrupt_manager.cpp
index 463d2916c..c3fffa894 100644
--- a/src/core/hardware_interrupt_manager.cpp
+++ b/src/core/hardware_interrupt_manager.cpp
@@ -8,14 +8,17 @@ namespace Core::Hardware {
8 8
9InterruptManager::InterruptManager(Core::System& system_in) : system(system_in) { 9InterruptManager::InterruptManager(Core::System& system_in) : system(system_in) {
10 gpu_interrupt_event = 10 gpu_interrupt_event =
11 system.CoreTiming().RegisterEvent("GPUInterrupt", [this](u64 event_index, s64) { 11 system.CoreTiming().RegisterEvent("GPUInterrupt", [this](u64 message, s64) {
12 auto nvdrv = system.ServiceManager().GetService<Service::Nvidia::NVDRV>("nvdrv"); 12 auto nvdrv = system.ServiceManager().GetService<Service::Nvidia::NVDRV>("nvdrv");
13 nvdrv->SignalGPUInterrupt(static_cast<u32>(event_index)); 13 const u32 syncpt = static_cast<u32>(message >> 32);
14 const u32 value = static_cast<u32>(message & 0x00000000FFFFFFFFULL);
15 nvdrv->SignalGPUInterruptSyncpt(syncpt, value);
14 }); 16 });
15} 17}
16 18
17void InterruptManager::InterruptGPU(const u32 event_index) { 19void InterruptManager::GPUInterruptSyncpt(const u32 syncpoint_id, const u32 value) {
18 system.CoreTiming().ScheduleEvent(10, gpu_interrupt_event, static_cast<u64>(event_index)); 20 const u64 msg = (static_cast<u64>(syncpoint_id) << 32ULL) | value;
21 system.CoreTiming().ScheduleEvent(10, gpu_interrupt_event, msg);
19} 22}
20 23
21} // namespace Core::Hardware 24} // namespace Core::Hardware
diff --git a/src/core/hardware_interrupt_manager.h b/src/core/hardware_interrupt_manager.h
index fc565c88b..590392f75 100644
--- a/src/core/hardware_interrupt_manager.h
+++ b/src/core/hardware_interrupt_manager.h
@@ -14,7 +14,7 @@ public:
14 InterruptManager(Core::System& system); 14 InterruptManager(Core::System& system);
15 ~InterruptManager() = default; 15 ~InterruptManager() = default;
16 16
17 void InterruptGPU(const u32 event_index); 17 void GPUInterruptSyncpt(const u32 syncpoint_id, const u32 value);
18 18
19private: 19private:
20 Core::System& system; 20 Core::System& system;
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
index 02b078c2f..d41274616 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
@@ -109,7 +109,7 @@ u32 nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector<u8>&
109 } 109 }
110 params.value |= event_id; 110 params.value |= event_id;
111 events_interface.events[event_id].writable->Clear(); 111 events_interface.events[event_id].writable->Clear();
112 gpu.RegisterEvent(event_id, params.syncpt_id, params.threshold); 112 gpu.RegisterSyncptInterrupt(params.syncpt_id, params.threshold);
113 std::memcpy(output.data(), &params, sizeof(params)); 113 std::memcpy(output.data(), &params, sizeof(params));
114 gpu.Guard(false); 114 gpu.Guard(false);
115 return NvResult::Timeout; 115 return NvResult::Timeout;
@@ -159,9 +159,6 @@ u32 nvhost_ctrl::IocCtrlEventSignal(const std::vector<u8>& input, std::vector<u8
159 return NvResult::BadParameter; 159 return NvResult::BadParameter;
160 } 160 }
161 if (events_interface.status[event_id] == EventState::Waiting) { 161 if (events_interface.status[event_id] == EventState::Waiting) {
162 auto& gpu = system.GPU();
163 gpu.CancelEvent(event_id, events_interface.assigned_syncpt[event_id],
164 events_interface.assigned_value[event_id]);
165 events_interface.LiberateEvent(event_id); 162 events_interface.LiberateEvent(event_id);
166 } 163 }
167 return NvResult::Success; 164 return NvResult::Success;
diff --git a/src/core/hle/service/nvdrv/interface.cpp b/src/core/hle/service/nvdrv/interface.cpp
index c548f1223..a4cb8cb81 100644
--- a/src/core/hle/service/nvdrv/interface.cpp
+++ b/src/core/hle/service/nvdrv/interface.cpp
@@ -15,8 +15,8 @@
15 15
16namespace Service::Nvidia { 16namespace Service::Nvidia {
17 17
18void NVDRV::SignalGPUInterrupt(const u32 event_id) { 18void NVDRV::SignalGPUInterruptSyncpt(const u32 syncpoint_id, const u32 value) {
19 nvdrv->SignalEvent(event_id); 19 nvdrv->SignalSyncpt(syncpoint_id, value);
20} 20}
21 21
22void NVDRV::Open(Kernel::HLERequestContext& ctx) { 22void NVDRV::Open(Kernel::HLERequestContext& ctx) {
diff --git a/src/core/hle/service/nvdrv/interface.h b/src/core/hle/service/nvdrv/interface.h
index 09cf4bb12..10a0ecd52 100644
--- a/src/core/hle/service/nvdrv/interface.h
+++ b/src/core/hle/service/nvdrv/interface.h
@@ -19,7 +19,7 @@ public:
19 NVDRV(std::shared_ptr<Module> nvdrv, const char* name); 19 NVDRV(std::shared_ptr<Module> nvdrv, const char* name);
20 ~NVDRV() override; 20 ~NVDRV() override;
21 21
22 void SignalGPUInterrupt(const u32 event_id); 22 void SignalGPUInterruptSyncpt(const u32 syncpoint_id, const u32 value);
23 23
24private: 24private:
25 void Open(Kernel::HLERequestContext& ctx); 25 void Open(Kernel::HLERequestContext& ctx);
diff --git a/src/core/hle/service/nvdrv/nvdrv.cpp b/src/core/hle/service/nvdrv/nvdrv.cpp
index c68d29177..b87c228bd 100644
--- a/src/core/hle/service/nvdrv/nvdrv.cpp
+++ b/src/core/hle/service/nvdrv/nvdrv.cpp
@@ -89,13 +89,14 @@ ResultCode Module::Close(u32 fd) {
89 return RESULT_SUCCESS; 89 return RESULT_SUCCESS;
90} 90}
91 91
92void Module::SignalEvent(const u32 event_id) { 92void Module::SignalSyncpt(const u32 syncpoint_id, const u32 value) {
93 if (event_id >= 64) { 93 for (u32 i = 0; i < MaxNvEvents; i++) {
94 LOG_ERROR(Service_NVDRV, "Unexpected Event signalled!"); 94 if (events_interface.assigned_syncpt[i] == syncpoint_id &&
95 return; 95 events_interface.assigned_value[i] == value) {
96 events_interface.LiberateEvent(i);
97 events_interface.events[i].writable->Signal();
98 }
96 } 99 }
97 events_interface.LiberateEvent(event_id);
98 events_interface.events[event_id].writable->Signal();
99} 100}
100 101
101Kernel::SharedPtr<Kernel::ReadableEvent> Module::GetEvent(const u32 event_id) { 102Kernel::SharedPtr<Kernel::ReadableEvent> Module::GetEvent(const u32 event_id) {
diff --git a/src/core/hle/service/nvdrv/nvdrv.h b/src/core/hle/service/nvdrv/nvdrv.h
index 597acc9c6..97b48d150 100644
--- a/src/core/hle/service/nvdrv/nvdrv.h
+++ b/src/core/hle/service/nvdrv/nvdrv.h
@@ -73,6 +73,8 @@ struct EventsInterface {
73 void LiberateEvent(const u32 event_id) { 73 void LiberateEvent(const u32 event_id) {
74 status[event_id] = registered[event_id] ? EventState::Registered : EventState::Free; 74 status[event_id] = registered[event_id] ? EventState::Registered : EventState::Free;
75 events_mask &= ~(1 << event_id); 75 events_mask &= ~(1 << event_id);
76 assigned_syncpt[event_id] = 0xFFFFFFFF;
77 assigned_value[event_id] = 0;
76 } 78 }
77}; 79};
78 80
@@ -97,7 +99,7 @@ public:
97 /// Closes a device file descriptor and returns operation success. 99 /// Closes a device file descriptor and returns operation success.
98 ResultCode Close(u32 fd); 100 ResultCode Close(u32 fd);
99 101
100 void SignalEvent(const u32 event_id); 102 void SignalSyncpt(const u32 syncpoint_id, const u32 value);
101 103
102 Kernel::SharedPtr<Kernel::ReadableEvent> GetEvent(const u32 event_id); 104 Kernel::SharedPtr<Kernel::ReadableEvent> GetEvent(const u32 event_id);
103 105
diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp
index 086db0e69..efea23bf2 100644
--- a/src/video_core/gpu.cpp
+++ b/src/video_core/gpu.cpp
@@ -70,13 +70,13 @@ const DmaPusher& GPU::DmaPusher() const {
70void GPU::IncrementSyncPoint(const u32 syncpoint_id) { 70void GPU::IncrementSyncPoint(const u32 syncpoint_id) {
71 syncpoints[syncpoint_id]++; 71 syncpoints[syncpoint_id]++;
72 sync_mutex.lock(); 72 sync_mutex.lock();
73 if (!events[syncpoint_id].empty()) { 73 if (!syncpt_interrupts[syncpoint_id].empty()) {
74 u32 value = syncpoints[syncpoint_id].load(); 74 u32 value = syncpoints[syncpoint_id].load();
75 auto it = events[syncpoint_id].begin(); 75 auto it = syncpt_interrupts[syncpoint_id].begin();
76 while (it != events[syncpoint_id].end()) { 76 while (it != syncpt_interrupts[syncpoint_id].end()) {
77 if (value >= it->value) { 77 if (value >= *it) {
78 TriggerCpuInterrupt(it->event_id); 78 TriggerCpuInterrupt(syncpoint_id, *it);
79 it = events[syncpoint_id].erase(it); 79 it = syncpt_interrupts[syncpoint_id].erase(it);
80 continue; 80 continue;
81 } 81 }
82 it++; 82 it++;
@@ -89,19 +89,19 @@ u32 GPU::GetSyncpointValue(const u32 syncpoint_id) const {
89 return syncpoints[syncpoint_id].load(); 89 return syncpoints[syncpoint_id].load();
90} 90}
91 91
92void GPU::RegisterEvent(const u32 event_id, const u32 syncpoint_id, const u32 value) { 92void GPU::RegisterSyncptInterrupt(const u32 syncpoint_id, const u32 value) {
93 for (auto& ev : events[syncpoint_id]) { 93 for (u32 in_value : syncpt_interrupts[syncpoint_id]) {
94 if (ev.event_id == event_id && ev.value == value) 94 if (in_value == value)
95 return; 95 return;
96 } 96 }
97 events[syncpoint_id].emplace_back(event_id, value); 97 syncpt_interrupts[syncpoint_id].emplace_back(value);
98} 98}
99 99
100void GPU::CancelEvent(const u32 event_id, const u32 syncpoint_id, const u32 value) { 100void GPU::CancelSyncptInterrupt(const u32 syncpoint_id, const u32 value) {
101 auto it = events[syncpoint_id].begin(); 101 auto it = syncpt_interrupts[syncpoint_id].begin();
102 while (it != events[syncpoint_id].end()) { 102 while (it != syncpt_interrupts[syncpoint_id].end()) {
103 if (value == it->value) { 103 if (value == *it) {
104 it = events[syncpoint_id].erase(it); 104 it = syncpt_interrupts[syncpoint_id].erase(it);
105 return; 105 return;
106 } 106 }
107 it++; 107 it++;
diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h
index 18ac3237e..9bd618941 100644
--- a/src/video_core/gpu.h
+++ b/src/video_core/gpu.h
@@ -172,9 +172,9 @@ public:
172 172
173 u32 GetSyncpointValue(const u32 syncpoint_id) const; 173 u32 GetSyncpointValue(const u32 syncpoint_id) const;
174 174
175 void RegisterEvent(const u32 event_id, const u32 syncpoint_id, const u32 value); 175 void RegisterSyncptInterrupt(const u32 syncpoint_id, const u32 value);
176 176
177 void CancelEvent(const u32 event_id, const u32 syncpoint_id, const u32 value); 177 void CancelSyncptInterrupt(const u32 syncpoint_id, const u32 value);
178 178
179 void Guard(bool guard_set) { 179 void Guard(bool guard_set) {
180 if (guard_set) { 180 if (guard_set) {
@@ -253,7 +253,7 @@ public:
253 virtual void FlushAndInvalidateRegion(CacheAddr addr, u64 size) = 0; 253 virtual void FlushAndInvalidateRegion(CacheAddr addr, u64 size) = 0;
254 254
255protected: 255protected:
256 virtual void TriggerCpuInterrupt(const u32 event_id) const = 0; 256 virtual void TriggerCpuInterrupt(const u32 syncpoint_id, const u32 value) const = 0;
257 257
258private: 258private:
259 void ProcessBindMethod(const MethodCall& method_call); 259 void ProcessBindMethod(const MethodCall& method_call);
@@ -293,13 +293,7 @@ private:
293 293
294 std::array<std::atomic<u32>, Service::Nvidia::MaxSyncPoints> syncpoints{}; 294 std::array<std::atomic<u32>, Service::Nvidia::MaxSyncPoints> syncpoints{};
295 295
296 struct Event { 296 std::array<std::list<u32>, Service::Nvidia::MaxSyncPoints> syncpt_interrupts;
297 Event(const u32 event_id, const u32 value) : event_id(event_id), value(value) {}
298 u32 event_id;
299 u32 value;
300 };
301
302 std::array<std::list<Event>, Service::Nvidia::MaxSyncPoints> events;
303 297
304 std::mutex sync_mutex; 298 std::mutex sync_mutex;
305 299
diff --git a/src/video_core/gpu_asynch.cpp b/src/video_core/gpu_asynch.cpp
index 6b6f0f6ec..ea67be831 100644
--- a/src/video_core/gpu_asynch.cpp
+++ b/src/video_core/gpu_asynch.cpp
@@ -40,9 +40,9 @@ void GPUAsynch::FlushAndInvalidateRegion(CacheAddr addr, u64 size) {
40 gpu_thread.FlushAndInvalidateRegion(addr, size); 40 gpu_thread.FlushAndInvalidateRegion(addr, size);
41} 41}
42 42
43void GPUAsynch::TriggerCpuInterrupt(const u32 event_id) const { 43void GPUAsynch::TriggerCpuInterrupt(const u32 syncpoint_id, const u32 value) const {
44 auto& interrupt_manager = system.InterruptManager(); 44 auto& interrupt_manager = system.InterruptManager();
45 interrupt_manager.InterruptGPU(event_id); 45 interrupt_manager.GPUInterruptSyncpt(syncpoint_id, value);
46} 46}
47 47
48} // namespace VideoCommon 48} // namespace VideoCommon
diff --git a/src/video_core/gpu_asynch.h b/src/video_core/gpu_asynch.h
index d49e9b96e..5f1b2fb7d 100644
--- a/src/video_core/gpu_asynch.h
+++ b/src/video_core/gpu_asynch.h
@@ -28,7 +28,7 @@ public:
28 void FlushAndInvalidateRegion(CacheAddr addr, u64 size) override; 28 void FlushAndInvalidateRegion(CacheAddr addr, u64 size) override;
29 29
30protected: 30protected:
31 void TriggerCpuInterrupt(const u32 event_id) const override; 31 void TriggerCpuInterrupt(const u32 syncpoint_id, const u32 value) const override;
32 32
33private: 33private:
34 GPUThread::ThreadManager gpu_thread; 34 GPUThread::ThreadManager gpu_thread;
diff --git a/src/video_core/gpu_synch.h b/src/video_core/gpu_synch.h
index 09bda854a..58d258503 100644
--- a/src/video_core/gpu_synch.h
+++ b/src/video_core/gpu_synch.h
@@ -27,7 +27,7 @@ public:
27 void FlushAndInvalidateRegion(CacheAddr addr, u64 size) override; 27 void FlushAndInvalidateRegion(CacheAddr addr, u64 size) override;
28 28
29protected: 29protected:
30 void TriggerCpuInterrupt(const u32 event_id) const override {} 30 void TriggerCpuInterrupt(const u32 syncpoint_id, const u32 value) const override {}
31}; 31};
32 32
33} // namespace VideoCommon 33} // namespace VideoCommon