summaryrefslogtreecommitdiffstats
path: root/src/core/hle/service/nvdrv/interface.cpp
diff options
context:
space:
mode:
authorChloe Marcec <dmarcecguzman@gmail.com>2020-11-24 06:40:23 +0100
committerChloe Marcec <dmarcecguzman@gmail.com>2020-11-24 06:40:23 +0100
commitab25d1fe9a7e3678b868855eecd402eec2efd1d6 (patch)
tree0807e2c296751459e259026ab8dd47f095725f28 /src/core/hle/service/nvdrv/interface.cpp
parentFix warnings in core/frontend/input.h with [[maybe_unused]] (diff)
downloadyuzu-ab25d1fe9a7e3678b868855eecd402eec2efd1d6.tar
yuzu-ab25d1fe9a7e3678b868855eecd402eec2efd1d6.tar.gz
yuzu-ab25d1fe9a7e3678b868855eecd402eec2efd1d6.tar.bz2
yuzu-ab25d1fe9a7e3678b868855eecd402eec2efd1d6.tar.lz
yuzu-ab25d1fe9a7e3678b868855eecd402eec2efd1d6.tar.xz
yuzu-ab25d1fe9a7e3678b868855eecd402eec2efd1d6.tar.zst
yuzu-ab25d1fe9a7e3678b868855eecd402eec2efd1d6.zip
Diffstat (limited to '')
-rw-r--r--src/core/hle/service/nvdrv/interface.cpp93
1 files changed, 83 insertions, 10 deletions
diff --git a/src/core/hle/service/nvdrv/interface.cpp b/src/core/hle/service/nvdrv/interface.cpp
index f6c38e853..7bfa5cac9 100644
--- a/src/core/hle/service/nvdrv/interface.cpp
+++ b/src/core/hle/service/nvdrv/interface.cpp
@@ -61,10 +61,32 @@ void NVDRV::Ioctl1(Kernel::HLERequestContext& ctx) {
std::vector<u8> output_buffer(ctx.GetWriteBufferSize(0));
const auto input_buffer = ctx.ReadBuffer(0);
- const auto nv_result = nvdrv->Ioctl1(fd, command, input_buffer, output_buffer);
-
- if (command.is_out != 0) {
- ctx.WriteBuffer(output_buffer);
+ IoctlCtrl ctrl{};
+
+ const auto nv_result = nvdrv->Ioctl1(fd, command, input_buffer, output_buffer, ctrl);
+ if (ctrl.must_delay) {
+ ctrl.fresh_call = false;
+ ctx.SleepClientThread(
+ "NVServices::DelayedResponse", ctrl.timeout,
+ [=, this](std::shared_ptr<Kernel::Thread> thread, Kernel::HLERequestContext& ctx_,
+ Kernel::ThreadWakeupReason reason) {
+ IoctlCtrl ctrl2{ctrl};
+ std::vector<u8> tmp_output = output_buffer;
+ const auto nv_result2 = nvdrv->Ioctl1(fd, command, input_buffer, tmp_output, ctrl2);
+
+ if (command.is_out != 0) {
+ ctx.WriteBuffer(tmp_output);
+ }
+
+ IPC::ResponseBuilder rb{ctx_, 3};
+ rb.Push(RESULT_SUCCESS);
+ rb.PushEnum(nv_result2);
+ },
+ nvdrv->GetEventWriteable(ctrl.event_id));
+ } else {
+ if (command.is_out != 0) {
+ ctx.WriteBuffer(output_buffer);
+ }
}
IPC::ResponseBuilder rb{ctx, 3};
@@ -88,8 +110,35 @@ void NVDRV::Ioctl2(Kernel::HLERequestContext& ctx) {
const auto input_inlined_buffer = ctx.ReadBuffer(1);
std::vector<u8> output_buffer(ctx.GetWriteBufferSize(0));
+ IoctlCtrl ctrl{};
+
const auto nv_result =
- nvdrv->Ioctl2(fd, command, input_buffer, input_inlined_buffer, output_buffer);
+ nvdrv->Ioctl2(fd, command, input_buffer, input_inlined_buffer, output_buffer, ctrl);
+ if (ctrl.must_delay) {
+ ctrl.fresh_call = false;
+ ctx.SleepClientThread(
+ "NVServices::DelayedResponse", ctrl.timeout,
+ [=, this](std::shared_ptr<Kernel::Thread> thread, Kernel::HLERequestContext& ctx_,
+ Kernel::ThreadWakeupReason reason) {
+ IoctlCtrl ctrl2{ctrl};
+ std::vector<u8> tmp_output = output_buffer;
+ const auto nv_result2 = nvdrv->Ioctl2(fd, command, input_buffer,
+ input_inlined_buffer, tmp_output, ctrl2);
+
+ if (command.is_out != 0) {
+ ctx.WriteBuffer(tmp_output);
+ }
+
+ IPC::ResponseBuilder rb{ctx_, 3};
+ rb.Push(RESULT_SUCCESS);
+ rb.PushEnum(nv_result2);
+ },
+ nvdrv->GetEventWriteable(ctrl.event_id));
+ } else {
+ if (command.is_out != 0) {
+ ctx.WriteBuffer(output_buffer);
+ }
+ }
if (command.is_out != 0) {
ctx.WriteBuffer(output_buffer);
@@ -116,12 +165,36 @@ void NVDRV::Ioctl3(Kernel::HLERequestContext& ctx) {
std::vector<u8> output_buffer(ctx.GetWriteBufferSize(0));
std::vector<u8> output_buffer_inline(ctx.GetWriteBufferSize(1));
+ IoctlCtrl ctrl{};
const auto nv_result =
- nvdrv->Ioctl3(fd, command, input_buffer, output_buffer, output_buffer_inline);
-
- if (command.is_out != 0) {
- ctx.WriteBuffer(output_buffer, 0);
- ctx.WriteBuffer(output_buffer_inline, 1);
+ nvdrv->Ioctl3(fd, command, input_buffer, output_buffer, output_buffer_inline, ctrl);
+ if (ctrl.must_delay) {
+ ctrl.fresh_call = false;
+ ctx.SleepClientThread(
+ "NVServices::DelayedResponse", ctrl.timeout,
+ [=, this](std::shared_ptr<Kernel::Thread> thread, Kernel::HLERequestContext& ctx_,
+ Kernel::ThreadWakeupReason reason) {
+ IoctlCtrl ctrl2{ctrl};
+ std::vector<u8> tmp_output = output_buffer;
+ std::vector<u8> tmp_output2 = output_buffer;
+ const auto nv_result2 =
+ nvdrv->Ioctl3(fd, command, input_buffer, tmp_output, tmp_output2, ctrl2);
+
+ if (command.is_out != 0) {
+ ctx.WriteBuffer(tmp_output, 0);
+ ctx.WriteBuffer(tmp_output2, 1);
+ }
+
+ IPC::ResponseBuilder rb{ctx_, 3};
+ rb.Push(RESULT_SUCCESS);
+ rb.PushEnum(nv_result2);
+ },
+ nvdrv->GetEventWriteable(ctrl.event_id));
+ } else {
+ if (command.is_out != 0) {
+ ctx.WriteBuffer(output_buffer, 0);
+ ctx.WriteBuffer(output_buffer_inline, 1);
+ }
}
IPC::ResponseBuilder rb{ctx, 3};