From bd1b67492a35be1bcd5a2cac43682cff01a60a6e Mon Sep 17 00:00:00 2001 From: Frodo Baggins Date: Wed, 11 Sep 2024 18:39:13 -0700 Subject: [PATCH] Fix copyGpuBuffers when resize invalidates commands in flight --- src/core/libraries/gnmdriver/gnmdriver.cpp | 4 ++++ src/video_core/amdgpu/liverpool.cpp | 6 ++++++ src/video_core/amdgpu/liverpool.h | 9 +++++++++ 3 files changed, 19 insertions(+) diff --git a/src/core/libraries/gnmdriver/gnmdriver.cpp b/src/core/libraries/gnmdriver/gnmdriver.cpp index 645bcf423..f078550af 100644 --- a/src/core/libraries/gnmdriver/gnmdriver.cpp +++ b/src/core/libraries/gnmdriver/gnmdriver.cpp @@ -2667,6 +2667,10 @@ void RegisterlibSceGnmDriver(Core::Loader::SymbolsResolver* sym) { sdk_version = 0; } + if (Config::copyGPUCmdBuffers()) { + liverpool->reserveCopyBufferSpace(); + } + Platform::IrqC::Instance()->Register(Platform::InterruptId::GpuIdle, ResetSubmissionLock, nullptr); diff --git a/src/video_core/amdgpu/liverpool.cpp b/src/video_core/amdgpu/liverpool.cpp index a2bd60f2e..74e623e3d 100644 --- a/src/video_core/amdgpu/liverpool.cpp +++ b/src/video_core/amdgpu/liverpool.cpp @@ -660,6 +660,12 @@ std::pair, std::span> Liverpool::CopyCmdBuffers( std::span dcb, std::span ccb) { auto& queue = mapped_queues[GfxQueueId]; + // std::vector resize can invalidate spans for commands in flight + ASSERT_MSG(queue.dcb_buffer.capacity() >= queue.dcb_buffer_offset + dcb.size(), + "dcb copy buffer out of reserved space"); + ASSERT_MSG(queue.ccb_buffer.capacity() >= queue.ccb_buffer_offset + ccb.size(), + "ccb copy buffer out of reserved space"); + queue.dcb_buffer.resize( std::max(queue.dcb_buffer.size(), queue.dcb_buffer_offset + dcb.size())); queue.ccb_buffer.resize( diff --git a/src/video_core/amdgpu/liverpool.h b/src/video_core/amdgpu/liverpool.h index 37720168a..d8e70f574 100644 --- a/src/video_core/amdgpu/liverpool.h +++ b/src/video_core/amdgpu/liverpool.h @@ -1088,6 +1088,15 @@ public: submit_cv.notify_one(); } + void reserveCopyBufferSpace() { + GpuQueue& gfx_queue = mapped_queues[GfxQueueId]; + std::scoped_lock lk(gfx_queue.m_access); + + constexpr size_t gfx_reserved_size = (2 << 21) / sizeof(u32); // 2MB + gfx_queue.ccb_buffer.reserve(gfx_reserved_size); + gfx_queue.dcb_buffer.reserve(gfx_reserved_size); + } + private: struct Task { struct promise_type {