diff options
| author | 2023-05-11 17:09:19 -0400 | |
|---|---|---|
| committer | 2023-05-11 17:09:19 -0400 | |
| commit | bb94beed15a4b95a896dfd68160e386c0be7b063 (patch) | |
| tree | 6d19b6192706f9350df1f09cabd1ccbbf933b027 | |
| parent | nvnflinger: fix producer slot fence init (diff) | |
| download | yuzu-bb94beed15a4b95a896dfd68160e386c0be7b063.tar.gz yuzu-bb94beed15a4b95a896dfd68160e386c0be7b063.tar.xz yuzu-bb94beed15a4b95a896dfd68160e386c0be7b063.zip | |
nvnflinger: fix Parcel serialization
| -rw-r--r-- | src/core/hle/service/nvnflinger/buffer_queue_producer.cpp | 4 | ||||
| -rw-r--r-- | src/core/hle/service/nvnflinger/parcel.h | 72 | ||||
| -rw-r--r-- | src/core/hle/service/vi/vi.cpp | 12 |
3 files changed, 49 insertions, 39 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 | |||
| 855 | status = DequeueBuffer(&slot, &fence, is_async, width, height, pixel_format, usage); | 855 | status = DequeueBuffer(&slot, &fence, is_async, width, height, pixel_format, usage); |
| 856 | 856 | ||
| 857 | parcel_out.Write(slot); | 857 | parcel_out.Write(slot); |
| 858 | parcel_out.WriteObject(&fence); | 858 | parcel_out.WriteFlattenedObject(&fence); |
| 859 | break; | 859 | break; |
| 860 | } | 860 | } |
| 861 | case TransactionId::RequestBuffer: { | 861 | case TransactionId::RequestBuffer: { |
| @@ -865,7 +865,7 @@ void BufferQueueProducer::Transact(HLERequestContext& ctx, TransactionId code, u | |||
| 865 | 865 | ||
| 866 | status = RequestBuffer(slot, &buf); | 866 | status = RequestBuffer(slot, &buf); |
| 867 | 867 | ||
| 868 | parcel_out.WriteObject(buf); | 868 | parcel_out.WriteFlattenedObject(buf); |
| 869 | break; | 869 | break; |
| 870 | } | 870 | } |
| 871 | case TransactionId::QueueBuffer: { | 871 | 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: | |||
| 117 | 117 | ||
| 118 | class OutputParcel final { | 118 | class OutputParcel final { |
| 119 | public: | 119 | public: |
| 120 | static constexpr std::size_t DefaultBufferSize = 0x40; | 120 | OutputParcel() = default; |
| 121 | |||
| 122 | OutputParcel() : buffer(DefaultBufferSize) {} | ||
| 123 | |||
| 124 | template <typename T> | ||
| 125 | explicit OutputParcel(const T& out_data) : buffer(DefaultBufferSize) { | ||
| 126 | Write(out_data); | ||
| 127 | } | ||
| 128 | 121 | ||
| 129 | template <typename T> | 122 | template <typename T> |
| 130 | void Write(const T& val) { | 123 | void Write(const T& val) { |
| 131 | static_assert(std::is_trivially_copyable_v<T>, "T must be trivially copyable."); | 124 | this->WriteImpl(val, m_data_buffer); |
| 132 | |||
| 133 | if (buffer.size() < write_index + sizeof(T)) { | ||
| 134 | buffer.resize(buffer.size() + sizeof(T) + DefaultBufferSize); | ||
| 135 | } | ||
| 136 | |||
| 137 | std::memcpy(buffer.data() + write_index, &val, sizeof(T)); | ||
| 138 | write_index += sizeof(T); | ||
| 139 | write_index = Common::AlignUp(write_index, 4); | ||
| 140 | } | 125 | } |
| 141 | 126 | ||
| 142 | template <typename T> | 127 | template <typename T> |
| 143 | void WriteObject(const T* ptr) { | 128 | void WriteFlattenedObject(const T* ptr) { |
| 144 | static_assert(std::is_trivially_copyable_v<T>, "T must be trivially copyable."); | ||
| 145 | |||
| 146 | if (!ptr) { | 129 | if (!ptr) { |
| 147 | Write<u32>(0); | 130 | this->Write<u32>(0); |
| 148 | return; | 131 | return; |
| 149 | } | 132 | } |
| 150 | 133 | ||
| 151 | Write<u32>(1); | 134 | this->Write<u32>(1); |
| 152 | Write<s64>(sizeof(T)); | 135 | this->Write<s64>(sizeof(T)); |
| 153 | Write(*ptr); | 136 | this->Write(*ptr); |
| 154 | } | 137 | } |
| 155 | 138 | ||
| 156 | template <typename T> | 139 | template <typename T> |
| 157 | void WriteObject(const std::shared_ptr<T> ptr) { | 140 | void WriteFlattenedObject(const std::shared_ptr<T> ptr) { |
| 158 | WriteObject(ptr.get()); | 141 | this->WriteFlattenedObject(ptr.get()); |
| 142 | } | ||
| 143 | |||
| 144 | template <typename T> | ||
| 145 | void WriteInterface(const T& val) { | ||
| 146 | this->WriteImpl(val, m_data_buffer); | ||
| 147 | this->WriteImpl(0U, m_object_buffer); | ||
| 159 | } | 148 | } |
| 160 | 149 | ||
| 161 | std::vector<u8> Serialize() const { | 150 | std::vector<u8> Serialize() const { |
| 151 | std::vector<u8> output_buffer(sizeof(ParcelHeader) + m_data_buffer.size() + | ||
| 152 | m_object_buffer.size()); | ||
| 153 | |||
| 162 | ParcelHeader header{}; | 154 | ParcelHeader header{}; |
| 163 | header.data_size = static_cast<u32>(write_index - sizeof(ParcelHeader)); | 155 | header.data_size = static_cast<u32>(m_data_buffer.size()); |
| 164 | header.data_offset = sizeof(ParcelHeader); | 156 | header.data_offset = sizeof(ParcelHeader); |
| 165 | header.objects_size = 4; | 157 | header.objects_size = static_cast<u32>(m_object_buffer.size()); |
| 166 | header.objects_offset = static_cast<u32>(sizeof(ParcelHeader) + header.data_size); | 158 | header.objects_offset = header.data_offset + header.data_size; |
| 167 | std::memcpy(buffer.data(), &header, sizeof(ParcelHeader)); | 159 | |
| 160 | std::memcpy(output_buffer.data(), &header, sizeof(header)); | ||
| 161 | std::ranges::copy(m_data_buffer, output_buffer.data() + header.data_offset); | ||
| 162 | std::ranges::copy(m_object_buffer, output_buffer.data() + header.objects_offset); | ||
| 163 | |||
| 164 | return output_buffer; | ||
| 165 | } | ||
| 166 | |||
| 167 | private: | ||
| 168 | template <typename T> | ||
| 169 | requires(std::is_trivially_copyable_v<T>) | ||
| 170 | void WriteImpl(const T& val, std::vector<u8>& buffer) { | ||
| 171 | const size_t aligned_size = Common::AlignUp(sizeof(T), 4); | ||
| 172 | const size_t old_size = buffer.size(); | ||
| 173 | buffer.resize(old_size + aligned_size); | ||
| 168 | 174 | ||
| 169 | return buffer; | 175 | std::memcpy(buffer.data() + old_size, &val, sizeof(T)); |
| 170 | } | 176 | } |
| 171 | 177 | ||
| 172 | private: | 178 | private: |
| 173 | mutable std::vector<u8> buffer; | 179 | std::vector<u8> m_data_buffer; |
| 174 | std::size_t write_index = sizeof(ParcelHeader); | 180 | std::vector<u8> m_object_buffer; |
| 175 | }; | 181 | }; |
| 176 | 182 | ||
| 177 | } // namespace Service::android | 183 | } // 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: | |||
| 64 | private: | 64 | private: |
| 65 | const u32 magic = 2; | 65 | const u32 magic = 2; |
| 66 | const u32 process_id = 1; | 66 | const u32 process_id = 1; |
| 67 | const u32 id; | 67 | const u64 id; |
| 68 | INSERT_PADDING_WORDS(3); | 68 | INSERT_PADDING_WORDS(2); |
| 69 | std::array<u8, 8> dispdrv = {'d', 'i', 's', 'p', 'd', 'r', 'v', '\0'}; | 69 | std::array<u8, 8> dispdrv = {'d', 'i', 's', 'p', 'd', 'r', 'v', '\0'}; |
| 70 | INSERT_PADDING_WORDS(2); | 70 | INSERT_PADDING_WORDS(2); |
| 71 | }; | 71 | }; |
| @@ -608,7 +608,9 @@ private: | |||
| 608 | return; | 608 | return; |
| 609 | } | 609 | } |
| 610 | 610 | ||
| 611 | const auto parcel = android::OutputParcel{NativeWindow{*buffer_queue_id}}; | 611 | android::OutputParcel parcel; |
| 612 | parcel.WriteInterface(NativeWindow{*buffer_queue_id}); | ||
| 613 | |||
| 612 | const auto buffer_size = ctx.WriteBuffer(parcel.Serialize()); | 614 | const auto buffer_size = ctx.WriteBuffer(parcel.Serialize()); |
| 613 | 615 | ||
| 614 | IPC::ResponseBuilder rb{ctx, 4}; | 616 | IPC::ResponseBuilder rb{ctx, 4}; |
| @@ -654,7 +656,9 @@ private: | |||
| 654 | return; | 656 | return; |
| 655 | } | 657 | } |
| 656 | 658 | ||
| 657 | const auto parcel = android::OutputParcel{NativeWindow{*buffer_queue_id}}; | 659 | android::OutputParcel parcel; |
| 660 | parcel.WriteInterface(NativeWindow{*buffer_queue_id}); | ||
| 661 | |||
| 658 | const auto buffer_size = ctx.WriteBuffer(parcel.Serialize()); | 662 | const auto buffer_size = ctx.WriteBuffer(parcel.Serialize()); |
| 659 | 663 | ||
| 660 | IPC::ResponseBuilder rb{ctx, 6}; | 664 | IPC::ResponseBuilder rb{ctx, 6}; |