summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp33
-rw-r--r--src/core/hle/service/nvdrv/interface.cpp4
2 files changed, 14 insertions, 23 deletions
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
index ff6b1abae..708469bd5 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
@@ -62,16 +62,26 @@ u32 nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector<u8>&
62 return NvResult::BadParameter; 62 return NvResult::BadParameter;
63 } 63 }
64 64
65 u32 event_id = params.value & 0x00FF;
66
67 if (event_id >= MaxNvEvents) {
68 std::memcpy(output.data(), &params, sizeof(params));
69 return NvResult::BadParameter;
70 }
71
72 auto event = events_interface.events[event_id];
65 auto& gpu = system.GPU(); 73 auto& gpu = system.GPU();
66 // This is mostly to take into account unimplemented features. As synced 74 // This is mostly to take into account unimplemented features. As synced
67 // gpu is always synced. 75 // gpu is always synced.
68 if (!gpu.IsAsync()) { 76 if (!gpu.IsAsync()) {
77 event.writable->Signal();
69 return NvResult::Success; 78 return NvResult::Success;
70 } 79 }
71 auto lock = gpu.LockSync(); 80 auto lock = gpu.LockSync();
72 const u32 current_syncpoint_value = gpu.GetSyncpointValue(params.syncpt_id); 81 const u32 current_syncpoint_value = gpu.GetSyncpointValue(params.syncpt_id);
73 const s32 diff = current_syncpoint_value - params.threshold; 82 const s32 diff = current_syncpoint_value - params.threshold;
74 if (diff >= 0) { 83 if (diff >= 0) {
84 event.writable->Signal();
75 params.value = current_syncpoint_value; 85 params.value = current_syncpoint_value;
76 std::memcpy(output.data(), &params, sizeof(params)); 86 std::memcpy(output.data(), &params, sizeof(params));
77 return NvResult::Success; 87 return NvResult::Success;
@@ -87,27 +97,6 @@ u32 nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector<u8>&
87 return NvResult::Timeout; 97 return NvResult::Timeout;
88 } 98 }
89 99
90 u32 event_id;
91 if (is_async) {
92 event_id = params.value & 0x00FF;
93 if (event_id >= MaxNvEvents) {
94 std::memcpy(output.data(), &params, sizeof(params));
95 return NvResult::BadParameter;
96 }
97 } else {
98 if (ctrl.fresh_call) {
99 const auto result = events_interface.GetFreeEvent();
100 if (result) {
101 event_id = *result;
102 } else {
103 LOG_CRITICAL(Service_NVDRV, "No Free Events available!");
104 event_id = params.value & 0x00FF;
105 }
106 } else {
107 event_id = ctrl.event_id;
108 }
109 }
110
111 EventState status = events_interface.status[event_id]; 100 EventState status = events_interface.status[event_id];
112 if (event_id < MaxNvEvents || status == EventState::Free || status == EventState::Registered) { 101 if (event_id < MaxNvEvents || status == EventState::Free || status == EventState::Registered) {
113 events_interface.SetEventStatus(event_id, EventState::Waiting); 102 events_interface.SetEventStatus(event_id, EventState::Waiting);
@@ -119,7 +108,7 @@ u32 nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector<u8>&
119 params.value = ((params.syncpt_id & 0xfff) << 16) | 0x10000000; 108 params.value = ((params.syncpt_id & 0xfff) << 16) | 0x10000000;
120 } 109 }
121 params.value |= event_id; 110 params.value |= event_id;
122 events_interface.events[event_id].writable->Clear(); 111 event.writable->Clear();
123 gpu.RegisterSyncptInterrupt(params.syncpt_id, target_value); 112 gpu.RegisterSyncptInterrupt(params.syncpt_id, target_value);
124 if (!is_async && ctrl.fresh_call) { 113 if (!is_async && ctrl.fresh_call) {
125 ctrl.must_delay = true; 114 ctrl.must_delay = true;
diff --git a/src/core/hle/service/nvdrv/interface.cpp b/src/core/hle/service/nvdrv/interface.cpp
index 5e0c23602..68d139cfb 100644
--- a/src/core/hle/service/nvdrv/interface.cpp
+++ b/src/core/hle/service/nvdrv/interface.cpp
@@ -134,7 +134,9 @@ void NVDRV::QueryEvent(Kernel::HLERequestContext& ctx) {
134 IPC::ResponseBuilder rb{ctx, 3, 1}; 134 IPC::ResponseBuilder rb{ctx, 3, 1};
135 rb.Push(RESULT_SUCCESS); 135 rb.Push(RESULT_SUCCESS);
136 if (event_id < MaxNvEvents) { 136 if (event_id < MaxNvEvents) {
137 rb.PushCopyObjects(nvdrv->GetEvent(event_id)); 137 auto event = nvdrv->GetEvent(event_id);
138 event->Clear();
139 rb.PushCopyObjects(event);
138 rb.Push<u32>(NvResult::Success); 140 rb.Push<u32>(NvResult::Success);
139 } else { 141 } else {
140 rb.Push<u32>(0); 142 rb.Push<u32>(0);