summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Liam2023-05-11 17:09:19 -0400
committerGravatar Liam2023-05-11 17:09:19 -0400
commitbb94beed15a4b95a896dfd68160e386c0be7b063 (patch)
tree6d19b6192706f9350df1f09cabd1ccbbf933b027
parentnvnflinger: fix producer slot fence init (diff)
downloadyuzu-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.cpp4
-rw-r--r--src/core/hle/service/nvnflinger/parcel.h72
-rw-r--r--src/core/hle/service/vi/vi.cpp12
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
118class OutputParcel final { 118class OutputParcel final {
119public: 119public:
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
167private:
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
172private: 178private:
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:
64private: 64private:
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};