diff options
| author | 2019-06-07 11:34:55 -0400 | |
|---|---|---|
| committer | 2019-07-05 15:49:10 -0400 | |
| commit | 737e978f5b1440a044ef90f346c8616c2de49a81 (patch) | |
| tree | 42b3c99171a3929f64db141db81193a0067b3523 | |
| parent | nvflinger: Implement swap intervals (diff) | |
| download | yuzu-737e978f5b1440a044ef90f346c8616c2de49a81.tar.gz yuzu-737e978f5b1440a044ef90f346c8616c2de49a81.tar.xz yuzu-737e978f5b1440a044ef90f346c8616c2de49a81.zip | |
nv_services: Correct buffer queue fencing and GPFifo fencing
| -rw-r--r-- | src/core/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp | 8 | ||||
| -rw-r--r-- | src/core/hle/service/nvdrv/devices/nvhost_gpu.h | 22 | ||||
| -rw-r--r-- | src/core/hle/service/nvdrv/nvdata.h | 25 | ||||
| -rw-r--r-- | src/core/hle/service/nvdrv/nvdrv.h | 8 | ||||
| -rw-r--r-- | src/core/hle/service/nvflinger/buffer_queue.cpp | 9 | ||||
| -rw-r--r-- | src/core/hle/service/nvflinger/buffer_queue.h | 8 | ||||
| -rw-r--r-- | src/core/hle/service/vi/vi.cpp | 46 |
8 files changed, 70 insertions, 57 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 30eb9d82e..c22585bfb 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt | |||
| @@ -369,6 +369,7 @@ add_library(core STATIC | |||
| 369 | hle/service/nvdrv/devices/nvmap.h | 369 | hle/service/nvdrv/devices/nvmap.h |
| 370 | hle/service/nvdrv/interface.cpp | 370 | hle/service/nvdrv/interface.cpp |
| 371 | hle/service/nvdrv/interface.h | 371 | hle/service/nvdrv/interface.h |
| 372 | hle/service/nvdrv/nvdata.h | ||
| 372 | hle/service/nvdrv/nvdrv.cpp | 373 | hle/service/nvdrv/nvdrv.cpp |
| 373 | hle/service/nvdrv/nvdrv.h | 374 | hle/service/nvdrv/nvdrv.h |
| 374 | hle/service/nvdrv/nvmemp.cpp | 375 | hle/service/nvdrv/nvmemp.cpp |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp index 8ce7bc7a5..8a53eddb1 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp | |||
| @@ -155,8 +155,8 @@ u32 nvhost_gpu::SubmitGPFIFO(const std::vector<u8>& input, std::vector<u8>& outp | |||
| 155 | 155 | ||
| 156 | Core::System::GetInstance().GPU().PushGPUEntries(std::move(entries)); | 156 | Core::System::GetInstance().GPU().PushGPUEntries(std::move(entries)); |
| 157 | 157 | ||
| 158 | params.fence_out.id = 0; | 158 | // TODO(Blinkhawk): Figure how thoios fence is set |
| 159 | params.fence_out.value = 0; | 159 | // params.fence_out.value = 0; |
| 160 | std::memcpy(output.data(), ¶ms, sizeof(IoctlSubmitGpfifo)); | 160 | std::memcpy(output.data(), ¶ms, sizeof(IoctlSubmitGpfifo)); |
| 161 | return 0; | 161 | return 0; |
| 162 | } | 162 | } |
| @@ -176,8 +176,8 @@ u32 nvhost_gpu::KickoffPB(const std::vector<u8>& input, std::vector<u8>& output) | |||
| 176 | 176 | ||
| 177 | Core::System::GetInstance().GPU().PushGPUEntries(std::move(entries)); | 177 | Core::System::GetInstance().GPU().PushGPUEntries(std::move(entries)); |
| 178 | 178 | ||
| 179 | params.fence_out.id = 0; | 179 | // TODO(Blinkhawk): Figure how thoios fence is set |
| 180 | params.fence_out.value = 0; | 180 | // params.fence_out.value = 0; |
| 181 | std::memcpy(output.data(), ¶ms, output.size()); | 181 | std::memcpy(output.data(), ¶ms, output.size()); |
| 182 | return 0; | 182 | return 0; |
| 183 | } | 183 | } |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.h b/src/core/hle/service/nvdrv/devices/nvhost_gpu.h index 62beb5c0c..d95cedb09 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.h | |||
| @@ -113,11 +113,11 @@ private: | |||
| 113 | static_assert(sizeof(IoctlGetErrorNotification) == 16, | 113 | static_assert(sizeof(IoctlGetErrorNotification) == 16, |
| 114 | "IoctlGetErrorNotification is incorrect size"); | 114 | "IoctlGetErrorNotification is incorrect size"); |
| 115 | 115 | ||
| 116 | struct IoctlFence { | 116 | struct Fence { |
| 117 | u32_le id; | 117 | u32_le id; |
| 118 | u32_le value; | 118 | u32_le value; |
| 119 | }; | 119 | }; |
| 120 | static_assert(sizeof(IoctlFence) == 8, "IoctlFence is incorrect size"); | 120 | static_assert(sizeof(Fence) == 8, "Fence is incorrect size"); |
| 121 | 121 | ||
| 122 | struct IoctlAllocGpfifoEx { | 122 | struct IoctlAllocGpfifoEx { |
| 123 | u32_le num_entries; | 123 | u32_le num_entries; |
| @@ -132,13 +132,13 @@ private: | |||
| 132 | static_assert(sizeof(IoctlAllocGpfifoEx) == 32, "IoctlAllocGpfifoEx is incorrect size"); | 132 | static_assert(sizeof(IoctlAllocGpfifoEx) == 32, "IoctlAllocGpfifoEx is incorrect size"); |
| 133 | 133 | ||
| 134 | struct IoctlAllocGpfifoEx2 { | 134 | struct IoctlAllocGpfifoEx2 { |
| 135 | u32_le num_entries; // in | 135 | u32_le num_entries; // in |
| 136 | u32_le flags; // in | 136 | u32_le flags; // in |
| 137 | u32_le unk0; // in (1 works) | 137 | u32_le unk0; // in (1 works) |
| 138 | IoctlFence fence_out; // out | 138 | Fence fence_out; // out |
| 139 | u32_le unk1; // in | 139 | u32_le unk1; // in |
| 140 | u32_le unk2; // in | 140 | u32_le unk2; // in |
| 141 | u32_le unk3; // in | 141 | u32_le unk3; // in |
| 142 | }; | 142 | }; |
| 143 | static_assert(sizeof(IoctlAllocGpfifoEx2) == 32, "IoctlAllocGpfifoEx2 is incorrect size"); | 143 | static_assert(sizeof(IoctlAllocGpfifoEx2) == 32, "IoctlAllocGpfifoEx2 is incorrect size"); |
| 144 | 144 | ||
| @@ -154,9 +154,9 @@ private: | |||
| 154 | u64_le address; // pointer to gpfifo entry structs | 154 | u64_le address; // pointer to gpfifo entry structs |
| 155 | u32_le num_entries; // number of fence objects being submitted | 155 | u32_le num_entries; // number of fence objects being submitted |
| 156 | u32_le flags; | 156 | u32_le flags; |
| 157 | IoctlFence fence_out; // returned new fence object for others to wait on | 157 | Fence fence_out; // returned new fence object for others to wait on |
| 158 | }; | 158 | }; |
| 159 | static_assert(sizeof(IoctlSubmitGpfifo) == 16 + sizeof(IoctlFence), | 159 | static_assert(sizeof(IoctlSubmitGpfifo) == 16 + sizeof(Fence), |
| 160 | "IoctlSubmitGpfifo is incorrect size"); | 160 | "IoctlSubmitGpfifo is incorrect size"); |
| 161 | 161 | ||
| 162 | struct IoctlGetWaitbase { | 162 | struct IoctlGetWaitbase { |
diff --git a/src/core/hle/service/nvdrv/nvdata.h b/src/core/hle/service/nvdrv/nvdata.h new file mode 100644 index 000000000..7e1dce232 --- /dev/null +++ b/src/core/hle/service/nvdrv/nvdata.h | |||
| @@ -0,0 +1,25 @@ | |||
| 1 | #pragma once | ||
| 2 | |||
| 3 | #include <array> | ||
| 4 | #include "common/common_types.h" | ||
| 5 | |||
| 6 | namespace Service::Nvidia { | ||
| 7 | |||
| 8 | struct Fence { | ||
| 9 | s32 id; | ||
| 10 | u32 value; | ||
| 11 | }; | ||
| 12 | |||
| 13 | static_assert(sizeof(Fence) == 8, "Fence has wrong size"); | ||
| 14 | |||
| 15 | struct MultiFence { | ||
| 16 | u32 num_fences; | ||
| 17 | std::array<Fence, 4> fences; | ||
| 18 | }; | ||
| 19 | |||
| 20 | enum class NvResult : u32 { | ||
| 21 | Success = 0, | ||
| 22 | TryAgain = 11, | ||
| 23 | }; | ||
| 24 | |||
| 25 | } // namespace Service::Nvidia | ||
diff --git a/src/core/hle/service/nvdrv/nvdrv.h b/src/core/hle/service/nvdrv/nvdrv.h index 53564f696..bacd7cdb7 100644 --- a/src/core/hle/service/nvdrv/nvdrv.h +++ b/src/core/hle/service/nvdrv/nvdrv.h | |||
| @@ -8,6 +8,7 @@ | |||
| 8 | #include <unordered_map> | 8 | #include <unordered_map> |
| 9 | #include <vector> | 9 | #include <vector> |
| 10 | #include "common/common_types.h" | 10 | #include "common/common_types.h" |
| 11 | #include "core/hle/service/nvdrv/nvdata.h" | ||
| 11 | #include "core/hle/service/service.h" | 12 | #include "core/hle/service/service.h" |
| 12 | 13 | ||
| 13 | namespace Service::NVFlinger { | 14 | namespace Service::NVFlinger { |
| @@ -20,13 +21,6 @@ namespace Devices { | |||
| 20 | class nvdevice; | 21 | class nvdevice; |
| 21 | } | 22 | } |
| 22 | 23 | ||
| 23 | struct IoctlFence { | ||
| 24 | u32 id; | ||
| 25 | u32 value; | ||
| 26 | }; | ||
| 27 | |||
| 28 | static_assert(sizeof(IoctlFence) == 8, "IoctlFence has wrong size"); | ||
| 29 | |||
| 30 | class Module final { | 24 | class Module final { |
| 31 | public: | 25 | public: |
| 32 | Module(); | 26 | Module(); |
diff --git a/src/core/hle/service/nvflinger/buffer_queue.cpp b/src/core/hle/service/nvflinger/buffer_queue.cpp index dca75c35e..75e47b8c7 100644 --- a/src/core/hle/service/nvflinger/buffer_queue.cpp +++ b/src/core/hle/service/nvflinger/buffer_queue.cpp | |||
| @@ -34,7 +34,8 @@ void BufferQueue::SetPreallocatedBuffer(u32 slot, const IGBPBuffer& igbp_buffer) | |||
| 34 | buffer_wait_event.writable->Signal(); | 34 | buffer_wait_event.writable->Signal(); |
| 35 | } | 35 | } |
| 36 | 36 | ||
| 37 | std::optional<u32> BufferQueue::DequeueBuffer(u32 width, u32 height) { | 37 | std::optional<std::pair<u32, Service::Nvidia::MultiFence*>> BufferQueue::DequeueBuffer(u32 width, |
| 38 | u32 height) { | ||
| 38 | auto itr = std::find_if(queue.begin(), queue.end(), [&](const Buffer& buffer) { | 39 | auto itr = std::find_if(queue.begin(), queue.end(), [&](const Buffer& buffer) { |
| 39 | // Only consider free buffers. Buffers become free once again after they've been Acquired | 40 | // Only consider free buffers. Buffers become free once again after they've been Acquired |
| 40 | // and Released by the compositor, see the NVFlinger::Compose method. | 41 | // and Released by the compositor, see the NVFlinger::Compose method. |
| @@ -51,7 +52,7 @@ std::optional<u32> BufferQueue::DequeueBuffer(u32 width, u32 height) { | |||
| 51 | } | 52 | } |
| 52 | 53 | ||
| 53 | itr->status = Buffer::Status::Dequeued; | 54 | itr->status = Buffer::Status::Dequeued; |
| 54 | return itr->slot; | 55 | return {{itr->slot, &itr->multi_fence}}; |
| 55 | } | 56 | } |
| 56 | 57 | ||
| 57 | const IGBPBuffer& BufferQueue::RequestBuffer(u32 slot) const { | 58 | const IGBPBuffer& BufferQueue::RequestBuffer(u32 slot) const { |
| @@ -63,7 +64,8 @@ const IGBPBuffer& BufferQueue::RequestBuffer(u32 slot) const { | |||
| 63 | } | 64 | } |
| 64 | 65 | ||
| 65 | void BufferQueue::QueueBuffer(u32 slot, BufferTransformFlags transform, | 66 | void BufferQueue::QueueBuffer(u32 slot, BufferTransformFlags transform, |
| 66 | const Common::Rectangle<int>& crop_rect, u32 swap_interval) { | 67 | const Common::Rectangle<int>& crop_rect, u32 swap_interval, |
| 68 | Service::Nvidia::MultiFence& multi_fence) { | ||
| 67 | auto itr = std::find_if(queue.begin(), queue.end(), | 69 | auto itr = std::find_if(queue.begin(), queue.end(), |
| 68 | [&](const Buffer& buffer) { return buffer.slot == slot; }); | 70 | [&](const Buffer& buffer) { return buffer.slot == slot; }); |
| 69 | ASSERT(itr != queue.end()); | 71 | ASSERT(itr != queue.end()); |
| @@ -72,6 +74,7 @@ void BufferQueue::QueueBuffer(u32 slot, BufferTransformFlags transform, | |||
| 72 | itr->transform = transform; | 74 | itr->transform = transform; |
| 73 | itr->crop_rect = crop_rect; | 75 | itr->crop_rect = crop_rect; |
| 74 | itr->swap_interval = swap_interval; | 76 | itr->swap_interval = swap_interval; |
| 77 | itr->multi_fence = multi_fence; | ||
| 75 | } | 78 | } |
| 76 | 79 | ||
| 77 | std::optional<std::reference_wrapper<const BufferQueue::Buffer>> BufferQueue::AcquireBuffer() { | 80 | std::optional<std::reference_wrapper<const BufferQueue::Buffer>> BufferQueue::AcquireBuffer() { |
diff --git a/src/core/hle/service/nvflinger/buffer_queue.h b/src/core/hle/service/nvflinger/buffer_queue.h index 139b98b9f..c163e565c 100644 --- a/src/core/hle/service/nvflinger/buffer_queue.h +++ b/src/core/hle/service/nvflinger/buffer_queue.h | |||
| @@ -12,6 +12,7 @@ | |||
| 12 | #include "common/swap.h" | 12 | #include "common/swap.h" |
| 13 | #include "core/hle/kernel/object.h" | 13 | #include "core/hle/kernel/object.h" |
| 14 | #include "core/hle/kernel/writable_event.h" | 14 | #include "core/hle/kernel/writable_event.h" |
| 15 | #include "core/hle/service/nvdrv/nvdata.h" | ||
| 15 | 16 | ||
| 16 | namespace Service::NVFlinger { | 17 | namespace Service::NVFlinger { |
| 17 | 18 | ||
| @@ -69,13 +70,16 @@ public: | |||
| 69 | BufferTransformFlags transform; | 70 | BufferTransformFlags transform; |
| 70 | Common::Rectangle<int> crop_rect; | 71 | Common::Rectangle<int> crop_rect; |
| 71 | u32 swap_interval; | 72 | u32 swap_interval; |
| 73 | Service::Nvidia::MultiFence multi_fence; | ||
| 72 | }; | 74 | }; |
| 73 | 75 | ||
| 74 | void SetPreallocatedBuffer(u32 slot, const IGBPBuffer& igbp_buffer); | 76 | void SetPreallocatedBuffer(u32 slot, const IGBPBuffer& igbp_buffer); |
| 75 | std::optional<u32> DequeueBuffer(u32 width, u32 height); | 77 | std::optional<std::pair<u32, Service::Nvidia::MultiFence*>> DequeueBuffer(u32 width, |
| 78 | u32 height); | ||
| 76 | const IGBPBuffer& RequestBuffer(u32 slot) const; | 79 | const IGBPBuffer& RequestBuffer(u32 slot) const; |
| 77 | void QueueBuffer(u32 slot, BufferTransformFlags transform, | 80 | void QueueBuffer(u32 slot, BufferTransformFlags transform, |
| 78 | const Common::Rectangle<int>& crop_rect, u32 swap_interval); | 81 | const Common::Rectangle<int>& crop_rect, u32 swap_interval, |
| 82 | Service::Nvidia::MultiFence& multi_fence); | ||
| 79 | std::optional<std::reference_wrapper<const Buffer>> AcquireBuffer(); | 83 | std::optional<std::reference_wrapper<const Buffer>> AcquireBuffer(); |
| 80 | void ReleaseBuffer(u32 slot); | 84 | void ReleaseBuffer(u32 slot); |
| 81 | u32 Query(QueryType type); | 85 | u32 Query(QueryType type); |
diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp index 55bd252c2..894bcdc04 100644 --- a/src/core/hle/service/vi/vi.cpp +++ b/src/core/hle/service/vi/vi.cpp | |||
| @@ -21,6 +21,7 @@ | |||
| 21 | #include "core/hle/kernel/readable_event.h" | 21 | #include "core/hle/kernel/readable_event.h" |
| 22 | #include "core/hle/kernel/thread.h" | 22 | #include "core/hle/kernel/thread.h" |
| 23 | #include "core/hle/kernel/writable_event.h" | 23 | #include "core/hle/kernel/writable_event.h" |
| 24 | #include "core/hle/service/nvdrv/nvdata.h" | ||
| 24 | #include "core/hle/service/nvdrv/nvdrv.h" | 25 | #include "core/hle/service/nvdrv/nvdrv.h" |
| 25 | #include "core/hle/service/nvflinger/buffer_queue.h" | 26 | #include "core/hle/service/nvflinger/buffer_queue.h" |
| 26 | #include "core/hle/service/nvflinger/nvflinger.h" | 27 | #include "core/hle/service/nvflinger/nvflinger.h" |
| @@ -328,32 +329,22 @@ public: | |||
| 328 | Data data; | 329 | Data data; |
| 329 | }; | 330 | }; |
| 330 | 331 | ||
| 331 | struct BufferProducerFence { | ||
| 332 | u32 is_valid; | ||
| 333 | std::array<Nvidia::IoctlFence, 4> fences; | ||
| 334 | }; | ||
| 335 | static_assert(sizeof(BufferProducerFence) == 36, "BufferProducerFence has wrong size"); | ||
| 336 | |||
| 337 | class IGBPDequeueBufferResponseParcel : public Parcel { | 332 | class IGBPDequeueBufferResponseParcel : public Parcel { |
| 338 | public: | 333 | public: |
| 339 | explicit IGBPDequeueBufferResponseParcel(u32 slot) : slot(slot) {} | 334 | explicit IGBPDequeueBufferResponseParcel(u32 slot, Service::Nvidia::MultiFence& multi_fence) |
| 335 | : slot(slot), multi_fence(multi_fence) {} | ||
| 340 | ~IGBPDequeueBufferResponseParcel() override = default; | 336 | ~IGBPDequeueBufferResponseParcel() override = default; |
| 341 | 337 | ||
| 342 | protected: | 338 | protected: |
| 343 | void SerializeData() override { | 339 | void SerializeData() override { |
| 344 | // TODO(Subv): Find out how this Fence is used. | ||
| 345 | BufferProducerFence fence = {}; | ||
| 346 | fence.is_valid = 1; | ||
| 347 | for (auto& fence_ : fence.fences) | ||
| 348 | fence_.id = -1; | ||
| 349 | |||
| 350 | Write(slot); | 340 | Write(slot); |
| 351 | Write<u32_le>(1); | 341 | Write<u32_le>(1); |
| 352 | WriteObject(fence); | 342 | WriteObject(multi_fence); |
| 353 | Write<u32_le>(0); | 343 | Write<u32_le>(0); |
| 354 | } | 344 | } |
| 355 | 345 | ||
| 356 | u32_le slot; | 346 | u32_le slot; |
| 347 | Service::Nvidia::MultiFence multi_fence; | ||
| 357 | }; | 348 | }; |
| 358 | 349 | ||
| 359 | class IGBPRequestBufferRequestParcel : public Parcel { | 350 | class IGBPRequestBufferRequestParcel : public Parcel { |
| @@ -400,12 +391,6 @@ public: | |||
| 400 | data = Read<Data>(); | 391 | data = Read<Data>(); |
| 401 | } | 392 | } |
| 402 | 393 | ||
| 403 | struct Fence { | ||
| 404 | u32_le id; | ||
| 405 | u32_le value; | ||
| 406 | }; | ||
| 407 | static_assert(sizeof(Fence) == 8, "Fence has wrong size"); | ||
| 408 | |||
| 409 | struct Data { | 394 | struct Data { |
| 410 | u32_le slot; | 395 | u32_le slot; |
| 411 | INSERT_PADDING_WORDS(3); | 396 | INSERT_PADDING_WORDS(3); |
| @@ -420,14 +405,13 @@ public: | |||
| 420 | u32_le sticky_transform; | 405 | u32_le sticky_transform; |
| 421 | INSERT_PADDING_WORDS(1); | 406 | INSERT_PADDING_WORDS(1); |
| 422 | u32_le swap_interval; | 407 | u32_le swap_interval; |
| 423 | u32_le fence_is_valid; | 408 | Service::Nvidia::MultiFence multi_fence; |
| 424 | std::array<Fence, 2> fences; | ||
| 425 | 409 | ||
| 426 | Common::Rectangle<int> GetCropRect() const { | 410 | Common::Rectangle<int> GetCropRect() const { |
| 427 | return {crop_left, crop_top, crop_right, crop_bottom}; | 411 | return {crop_left, crop_top, crop_right, crop_bottom}; |
| 428 | } | 412 | } |
| 429 | }; | 413 | }; |
| 430 | static_assert(sizeof(Data) == 80, "ParcelData has wrong size"); | 414 | static_assert(sizeof(Data) == 96, "ParcelData has wrong size"); |
| 431 | 415 | ||
| 432 | Data data; | 416 | Data data; |
| 433 | }; | 417 | }; |
| @@ -548,11 +532,11 @@ private: | |||
| 548 | IGBPDequeueBufferRequestParcel request{ctx.ReadBuffer()}; | 532 | IGBPDequeueBufferRequestParcel request{ctx.ReadBuffer()}; |
| 549 | const u32 width{request.data.width}; | 533 | const u32 width{request.data.width}; |
| 550 | const u32 height{request.data.height}; | 534 | const u32 height{request.data.height}; |
| 551 | std::optional<u32> slot = buffer_queue.DequeueBuffer(width, height); | 535 | auto result = buffer_queue.DequeueBuffer(width, height); |
| 552 | 536 | ||
| 553 | if (slot) { | 537 | if (result) { |
| 554 | // Buffer is available | 538 | // Buffer is available |
| 555 | IGBPDequeueBufferResponseParcel response{*slot}; | 539 | IGBPDequeueBufferResponseParcel response{(*result).first, *(*result).second}; |
| 556 | ctx.WriteBuffer(response.Serialize()); | 540 | ctx.WriteBuffer(response.Serialize()); |
| 557 | } else { | 541 | } else { |
| 558 | // Wait the current thread until a buffer becomes available | 542 | // Wait the current thread until a buffer becomes available |
| @@ -562,10 +546,11 @@ private: | |||
| 562 | Kernel::ThreadWakeupReason reason) { | 546 | Kernel::ThreadWakeupReason reason) { |
| 563 | // Repeat TransactParcel DequeueBuffer when a buffer is available | 547 | // Repeat TransactParcel DequeueBuffer when a buffer is available |
| 564 | auto& buffer_queue = nv_flinger->FindBufferQueue(id); | 548 | auto& buffer_queue = nv_flinger->FindBufferQueue(id); |
| 565 | std::optional<u32> slot = buffer_queue.DequeueBuffer(width, height); | 549 | auto result = buffer_queue.DequeueBuffer(width, height); |
| 566 | ASSERT_MSG(slot != std::nullopt, "Could not dequeue buffer."); | 550 | ASSERT_MSG(result != std::nullopt, "Could not dequeue buffer."); |
| 567 | 551 | ||
| 568 | IGBPDequeueBufferResponseParcel response{*slot}; | 552 | IGBPDequeueBufferResponseParcel response{(*result).first, |
| 553 | *(*result).second}; | ||
| 569 | ctx.WriteBuffer(response.Serialize()); | 554 | ctx.WriteBuffer(response.Serialize()); |
| 570 | IPC::ResponseBuilder rb{ctx, 2}; | 555 | IPC::ResponseBuilder rb{ctx, 2}; |
| 571 | rb.Push(RESULT_SUCCESS); | 556 | rb.Push(RESULT_SUCCESS); |
| @@ -583,7 +568,8 @@ private: | |||
| 583 | IGBPQueueBufferRequestParcel request{ctx.ReadBuffer()}; | 568 | IGBPQueueBufferRequestParcel request{ctx.ReadBuffer()}; |
| 584 | 569 | ||
| 585 | buffer_queue.QueueBuffer(request.data.slot, request.data.transform, | 570 | buffer_queue.QueueBuffer(request.data.slot, request.data.transform, |
| 586 | request.data.GetCropRect(), request.data.swap_interval); | 571 | request.data.GetCropRect(), request.data.swap_interval, |
| 572 | request.data.multi_fence); | ||
| 587 | 573 | ||
| 588 | IGBPQueueBufferResponseParcel response{1280, 720}; | 574 | IGBPQueueBufferResponseParcel response{1280, 720}; |
| 589 | ctx.WriteBuffer(response.Serialize()); | 575 | ctx.WriteBuffer(response.Serialize()); |