From 8dee5663b3b2ae5dd1b5a4b9eeacf030caa0de9a Mon Sep 17 00:00:00 2001 From: Subv Date: Tue, 13 Feb 2018 22:12:46 -0500 Subject: [PATCH] Vi: Properly write the BufferProducerFence object in the DequeueBuffer response parcel. --- src/core/hle/service/nvdrv/nvdrv.h | 7 ++++++ src/core/hle/service/vi/vi.cpp | 39 ++++++++++++++++-------------- 2 files changed, 28 insertions(+), 18 deletions(-) diff --git a/src/core/hle/service/nvdrv/nvdrv.h b/src/core/hle/service/nvdrv/nvdrv.h index e44644624..6a55ff96d 100644 --- a/src/core/hle/service/nvdrv/nvdrv.h +++ b/src/core/hle/service/nvdrv/nvdrv.h @@ -17,6 +17,13 @@ namespace Devices { class nvdevice; } +struct IoctlFence { + u32 id; + u32 value; +}; + +static_assert(sizeof(IoctlFence) == 8, "IoctlFence has wrong size"); + class Module final { public: Module(); diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp index ff5005f71..9394a06a7 100644 --- a/src/core/hle/service/vi/vi.cpp +++ b/src/core/hle/service/vi/vi.cpp @@ -8,6 +8,7 @@ #include "common/scope_exit.h" #include "core/core_timing.h" #include "core/hle/ipc_helpers.h" +#include "core/hle/service/nvdrv/nvdrv.h" #include "core/hle/service/nvflinger/buffer_queue.h" #include "core/hle/service/vi/vi.h" #include "core/hle/service/vi/vi_m.h" @@ -86,6 +87,15 @@ public: write_index = Common::AlignUp(write_index, 4); } + template + void WriteObject(const T& val) { + u32_le size = static_cast(sizeof(val)); + Write(size); + // TODO(Subv): Support file descriptors. + Write(0); // Fd count. + Write(val); + } + void Deserialize() { Header header{}; std::memcpy(&header, buffer.data(), sizeof(Header)); @@ -262,10 +272,11 @@ public: Data data; }; -// TODO(bunnei): Remove this. When set to 1, games will think a fence is valid and boot further. -// This will break libnx and potentially other apps that more stringently check this. This is here -// purely as a convenience, and should go away once we implement fences. -static constexpr u32 FENCE_HACK = 0; +struct BufferProducerFence { + u32 is_valid; + std::array fences; +}; +static_assert(sizeof(BufferProducerFence) == 36, "BufferProducerFence has wrong size"); class IGBPDequeueBufferResponseParcel : public Parcel { public: @@ -274,20 +285,12 @@ public: protected: void SerializeData() override { - // TODO(bunnei): Find out what this all means. Writing anything non-zero here breaks libnx. - Write(0); - Write(FENCE_HACK); - Write(0); - Write(0); - Write(0); - Write(0); - Write(0); - Write(0); - Write(0); - Write(0); - Write(0); - Write(0); - Write(0); + // TODO(Subv): Find out how this Fence is used. + BufferProducerFence fence = {}; + + Write(slot); + WriteObject(fence); + Write(0); } u32_le slot;