diff --git a/src/core/libraries/gnmdriver/gnmdriver.cpp b/src/core/libraries/gnmdriver/gnmdriver.cpp index 645bcf42..f078550a 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 a2bd60f2..74e623e3 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 37720168..89723ccb 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 GfxReservedSize = 2_MB >> 2; + gfx_queue.ccb_buffer.reserve(GfxReservedSize); + gfx_queue.dcb_buffer.reserve(GfxReservedSize); + } + private: struct Task { struct promise_type {