diff options
author | Fernando Sahmkow <fsahmkow27@gmail.com> | 2019-06-16 17:43:41 +0200 |
---|---|---|
committer | FernandoS27 <fsahmkow27@gmail.com> | 2019-07-05 21:49:28 +0200 |
commit | b6844bec608ed82511738e9f3911e72aeb05243a (patch) | |
tree | 4a06bdb82d2cbceedee70ac41725c7354d1ec723 /src/core/hle/service/nvdrv/interface.cpp | |
parent | GPU: Correct Interrupts to interrupt on syncpt/value instead of event, mirroring hardware (diff) | |
download | yuzu-b6844bec608ed82511738e9f3911e72aeb05243a.tar yuzu-b6844bec608ed82511738e9f3911e72aeb05243a.tar.gz yuzu-b6844bec608ed82511738e9f3911e72aeb05243a.tar.bz2 yuzu-b6844bec608ed82511738e9f3911e72aeb05243a.tar.lz yuzu-b6844bec608ed82511738e9f3911e72aeb05243a.tar.xz yuzu-b6844bec608ed82511738e9f3911e72aeb05243a.tar.zst yuzu-b6844bec608ed82511738e9f3911e72aeb05243a.zip |
Diffstat (limited to 'src/core/hle/service/nvdrv/interface.cpp')
-rw-r--r-- | src/core/hle/service/nvdrv/interface.cpp | 34 |
1 files changed, 30 insertions, 4 deletions
diff --git a/src/core/hle/service/nvdrv/interface.cpp b/src/core/hle/service/nvdrv/interface.cpp index a4cb8cb81..45912153d 100644 --- a/src/core/hle/service/nvdrv/interface.cpp +++ b/src/core/hle/service/nvdrv/interface.cpp @@ -8,6 +8,7 @@ #include "core/hle/ipc_helpers.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/readable_event.h" +#include "core/hle/kernel/thread.h" #include "core/hle/kernel/writable_event.h" #include "core/hle/service/nvdrv/interface.h" #include "core/hle/service/nvdrv/nvdata.h" @@ -41,11 +42,36 @@ void NVDRV::Ioctl(Kernel::HLERequestContext& ctx) { std::vector<u8> output(ctx.GetWriteBufferSize()); - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(RESULT_SUCCESS); - rb.Push(nvdrv->Ioctl(fd, command, ctx.ReadBuffer(), output)); + IoctlCtrl ctrl{}; + + u32 result = nvdrv->Ioctl(fd, command, ctx.ReadBuffer(), output, ctrl); - ctx.WriteBuffer(output); + if (!ctrl.must_delay) { + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(RESULT_SUCCESS); + rb.Push(result); + + ctx.WriteBuffer(output); + return; + } + ctrl.fresh_call = false; + ctx.SleepClientThread( + "NVServices::DelayedResponse", ctrl.timeout, + [this, ctrl = ctrl](Kernel::SharedPtr<Kernel::Thread> thread, Kernel::HLERequestContext& ctx, + Kernel::ThreadWakeupReason reason) { + IPC::RequestParser rp{ctx}; + u32 fd = rp.Pop<u32>(); + u32 command = rp.Pop<u32>(); + std::vector<u8> output(ctx.GetWriteBufferSize()); + IoctlCtrl ctrl2{ctrl}; + u32 result = nvdrv->Ioctl(fd, command, ctx.ReadBuffer(), output, ctrl2); + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(RESULT_SUCCESS); + rb.Push(result); + + ctx.WriteBuffer(output); + }, + nvdrv->GetEventWriteable(ctrl.event_id)); } void NVDRV::Close(Kernel::HLERequestContext& ctx) { |