From 6e10a0c1305f4210f725da03cfc5ebc4e34a672c Mon Sep 17 00:00:00 2001
From: Liam <byteslice@airmail.cc>
Date: Thu, 11 May 2023 17:08:14 -0400
Subject: [PATCH 1/2] nvnflinger: fix producer slot fence init

---
 src/core/hle/service/nvnflinger/buffer_queue_producer.cpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/core/hle/service/nvnflinger/buffer_queue_producer.cpp b/src/core/hle/service/nvnflinger/buffer_queue_producer.cpp
index cd0a13094..c9e9fedd1 100644
--- a/src/core/hle/service/nvnflinger/buffer_queue_producer.cpp
+++ b/src/core/hle/service/nvnflinger/buffer_queue_producer.cpp
@@ -793,6 +793,7 @@ Status BufferQueueProducer::SetPreallocatedBuffer(s32 slot,
     std::scoped_lock lock{core->mutex};
 
     slots[slot] = {};
+    slots[slot].fence = Fence::NoFence();
     slots[slot].graphic_buffer = buffer;
     slots[slot].frame_number = 0;
 

From bb94beed15a4b95a896dfd68160e386c0be7b063 Mon Sep 17 00:00:00 2001
From: Liam <byteslice@airmail.cc>
Date: Thu, 11 May 2023 17:09:19 -0400
Subject: [PATCH 2/2] nvnflinger: fix Parcel serialization

---
 .../nvnflinger/buffer_queue_producer.cpp      |  4 +-
 src/core/hle/service/nvnflinger/parcel.h      | 76 ++++++++++---------
 src/core/hle/service/vi/vi.cpp                | 12 ++-
 3 files changed, 51 insertions(+), 41 deletions(-)

diff --git a/src/core/hle/service/nvnflinger/buffer_queue_producer.cpp b/src/core/hle/service/nvnflinger/buffer_queue_producer.cpp
index c9e9fedd1..b16f9933f 100644
--- a/src/core/hle/service/nvnflinger/buffer_queue_producer.cpp
+++ b/src/core/hle/service/nvnflinger/buffer_queue_producer.cpp
@@ -855,7 +855,7 @@ void BufferQueueProducer::Transact(HLERequestContext& ctx, TransactionId code, u
         status = DequeueBuffer(&slot, &fence, is_async, width, height, pixel_format, usage);
 
         parcel_out.Write(slot);
-        parcel_out.WriteObject(&fence);
+        parcel_out.WriteFlattenedObject(&fence);
         break;
     }
     case TransactionId::RequestBuffer: {
@@ -865,7 +865,7 @@ void BufferQueueProducer::Transact(HLERequestContext& ctx, TransactionId code, u
 
         status = RequestBuffer(slot, &buf);
 
-        parcel_out.WriteObject(buf);
+        parcel_out.WriteFlattenedObject(buf);
         break;
     }
     case TransactionId::QueueBuffer: {
diff --git a/src/core/hle/service/nvnflinger/parcel.h b/src/core/hle/service/nvnflinger/parcel.h
index d1b6201e0..fb56d75d7 100644
--- a/src/core/hle/service/nvnflinger/parcel.h
+++ b/src/core/hle/service/nvnflinger/parcel.h
@@ -117,61 +117,67 @@ private:
 
 class OutputParcel final {
 public:
-    static constexpr std::size_t DefaultBufferSize = 0x40;
-
-    OutputParcel() : buffer(DefaultBufferSize) {}
-
-    template <typename T>
-    explicit OutputParcel(const T& out_data) : buffer(DefaultBufferSize) {
-        Write(out_data);
-    }
+    OutputParcel() = default;
 
     template <typename T>
     void Write(const T& val) {
-        static_assert(std::is_trivially_copyable_v<T>, "T must be trivially copyable.");
-
-        if (buffer.size() < write_index + sizeof(T)) {
-            buffer.resize(buffer.size() + sizeof(T) + DefaultBufferSize);
-        }
-
-        std::memcpy(buffer.data() + write_index, &val, sizeof(T));
-        write_index += sizeof(T);
-        write_index = Common::AlignUp(write_index, 4);
+        this->WriteImpl(val, m_data_buffer);
     }
 
     template <typename T>
-    void WriteObject(const T* ptr) {
-        static_assert(std::is_trivially_copyable_v<T>, "T must be trivially copyable.");
-
+    void WriteFlattenedObject(const T* ptr) {
         if (!ptr) {
-            Write<u32>(0);
+            this->Write<u32>(0);
             return;
         }
 
-        Write<u32>(1);
-        Write<s64>(sizeof(T));
-        Write(*ptr);
+        this->Write<u32>(1);
+        this->Write<s64>(sizeof(T));
+        this->Write(*ptr);
     }
 
     template <typename T>
-    void WriteObject(const std::shared_ptr<T> ptr) {
-        WriteObject(ptr.get());
+    void WriteFlattenedObject(const std::shared_ptr<T> ptr) {
+        this->WriteFlattenedObject(ptr.get());
+    }
+
+    template <typename T>
+    void WriteInterface(const T& val) {
+        this->WriteImpl(val, m_data_buffer);
+        this->WriteImpl(0U, m_object_buffer);
     }
 
     std::vector<u8> Serialize() const {
-        ParcelHeader header{};
-        header.data_size = static_cast<u32>(write_index - sizeof(ParcelHeader));
-        header.data_offset = sizeof(ParcelHeader);
-        header.objects_size = 4;
-        header.objects_offset = static_cast<u32>(sizeof(ParcelHeader) + header.data_size);
-        std::memcpy(buffer.data(), &header, sizeof(ParcelHeader));
+        std::vector<u8> output_buffer(sizeof(ParcelHeader) + m_data_buffer.size() +
+                                      m_object_buffer.size());
 
-        return buffer;
+        ParcelHeader header{};
+        header.data_size = static_cast<u32>(m_data_buffer.size());
+        header.data_offset = sizeof(ParcelHeader);
+        header.objects_size = static_cast<u32>(m_object_buffer.size());
+        header.objects_offset = header.data_offset + header.data_size;
+
+        std::memcpy(output_buffer.data(), &header, sizeof(header));
+        std::ranges::copy(m_data_buffer, output_buffer.data() + header.data_offset);
+        std::ranges::copy(m_object_buffer, output_buffer.data() + header.objects_offset);
+
+        return output_buffer;
     }
 
 private:
-    mutable std::vector<u8> buffer;
-    std::size_t write_index = sizeof(ParcelHeader);
+    template <typename T>
+        requires(std::is_trivially_copyable_v<T>)
+    void WriteImpl(const T& val, std::vector<u8>& buffer) {
+        const size_t aligned_size = Common::AlignUp(sizeof(T), 4);
+        const size_t old_size = buffer.size();
+        buffer.resize(old_size + aligned_size);
+
+        std::memcpy(buffer.data() + old_size, &val, sizeof(T));
+    }
+
+private:
+    std::vector<u8> m_data_buffer;
+    std::vector<u8> m_object_buffer;
 };
 
 } // namespace Service::android
diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp
index 68eab5133..1b193f00c 100644
--- a/src/core/hle/service/vi/vi.cpp
+++ b/src/core/hle/service/vi/vi.cpp
@@ -64,8 +64,8 @@ public:
 private:
     const u32 magic = 2;
     const u32 process_id = 1;
-    const u32 id;
-    INSERT_PADDING_WORDS(3);
+    const u64 id;
+    INSERT_PADDING_WORDS(2);
     std::array<u8, 8> dispdrv = {'d', 'i', 's', 'p', 'd', 'r', 'v', '\0'};
     INSERT_PADDING_WORDS(2);
 };
@@ -608,7 +608,9 @@ private:
             return;
         }
 
-        const auto parcel = android::OutputParcel{NativeWindow{*buffer_queue_id}};
+        android::OutputParcel parcel;
+        parcel.WriteInterface(NativeWindow{*buffer_queue_id});
+
         const auto buffer_size = ctx.WriteBuffer(parcel.Serialize());
 
         IPC::ResponseBuilder rb{ctx, 4};
@@ -654,7 +656,9 @@ private:
             return;
         }
 
-        const auto parcel = android::OutputParcel{NativeWindow{*buffer_queue_id}};
+        android::OutputParcel parcel;
+        parcel.WriteInterface(NativeWindow{*buffer_queue_id});
+
         const auto buffer_size = ctx.WriteBuffer(parcel.Serialize());
 
         IPC::ResponseBuilder rb{ctx, 6};