From 629dc6132ebc73b7e75c1b08307e5bd925286162 Mon Sep 17 00:00:00 2001 From: Lander Gallastegi Date: Sun, 27 Apr 2025 10:15:27 +0200 Subject: [PATCH] Some fixes (and async testing (doesn't work)) --- src/video_core/buffer_cache/buffer_cache.cpp | 55 ++++++++++--------- .../renderer_vulkan/vk_scheduler.cpp | 11 ++++ src/video_core/renderer_vulkan/vk_scheduler.h | 4 ++ 3 files changed, 44 insertions(+), 26 deletions(-) diff --git a/src/video_core/buffer_cache/buffer_cache.cpp b/src/video_core/buffer_cache/buffer_cache.cpp index eea9f6a7f..8bc2e2ec7 100644 --- a/src/video_core/buffer_cache/buffer_cache.cpp +++ b/src/video_core/buffer_cache/buffer_cache.cpp @@ -553,7 +553,6 @@ void BufferCache::CreateFaultBuffers() { .offset = 0, .size = FAULT_READBACK_SIZE, }; - staging_buffer.Commit(); scheduler.EndRendering(); const auto cmdbuf = scheduler.CommandBuffer(); cmdbuf.pipelineBarrier2(vk::DependencyInfo{ @@ -562,35 +561,39 @@ void BufferCache::CreateFaultBuffers() { .pBufferMemoryBarriers = &barrier, }); cmdbuf.copyBuffer(fault_readback_buffer.buffer, staging_buffer.Handle(), copy); - scheduler.Finish(); - std::memcpy(fault_readback_cpu.data(), mapped, FAULT_READBACK_SIZE); - // Create the fault buffers batched - boost::icl::interval_set fault_ranges; - for (u64 i = 0; i < FAULT_READBACK_SIZE; ++i) { - if (fault_readback_cpu[i] == 0) { - continue; - } - // Each bit is a page - const u64 page = i * 8; - for (u8 j = 0; j < 8; ++j) { - if ((fault_readback_cpu[i] & (1 << j)) == 0) { + staging_buffer.Commit(); + scheduler.DeferOperation([this, mapped]() { + std::memcpy(fault_readback_cpu.data(), mapped, FAULT_READBACK_SIZE); + // Create the fault buffers batched + boost::icl::interval_set fault_ranges; + for (u64 i = 0; i < FAULT_READBACK_SIZE; ++i) { + if (fault_readback_cpu[i] == 0) { continue; } - const VAddr start = (page + j) << CACHING_PAGEBITS; - const VAddr end = start + CACHING_PAGESIZE; - fault_ranges += boost::icl::interval_set::interval_type::right_open(start, end); - LOG_WARNING(Render_Vulkan, "Accessed non GPU-local memory at {:#x}", start); + // Each bit is a page + const u64 page = i * 8; + for (u8 j = 0; j < 8; ++j) { + if ((fault_readback_cpu[i] & (1 << j)) == 0) { + continue; + } + const VAddr start = (page + j) << CACHING_PAGEBITS; + const VAddr end = start + CACHING_PAGESIZE; + fault_ranges += + boost::icl::interval_set::interval_type::right_open(start, end); + LOG_WARNING(Render_Vulkan, "Accessed non GPU-local memory at {:#x}", start); + } } - } - for (const auto& range : fault_ranges) { - const VAddr start = range.lower(); - const u64 size = range.upper() - start; - // Buffer size is 32 bits - for (VAddr addr = start; addr < size; addr += std::numeric_limits::max()) { - const u32 size_buffer = std::min(size, std::numeric_limits::max()); - CreateBuffer(addr, size_buffer); + for (const auto& range : fault_ranges) { + const VAddr start = range.lower(); + const VAddr end = range.upper(); + // Buffer size is 32 bits + for (VAddr addr = start; addr < end; addr += std::numeric_limits::max()) { + const u32 size_buffer = std::min(end - addr, std::numeric_limits::max()); + CreateBuffer(addr, size_buffer); + } } - } + }); + scheduler.Flush(); } void BufferCache::ResetFaultReadbackBuffer() { diff --git a/src/video_core/renderer_vulkan/vk_scheduler.cpp b/src/video_core/renderer_vulkan/vk_scheduler.cpp index 8d4188a22..73a4d9a5a 100644 --- a/src/video_core/renderer_vulkan/vk_scheduler.cpp +++ b/src/video_core/renderer_vulkan/vk_scheduler.cpp @@ -70,6 +70,11 @@ void Scheduler::Flush(SubmitInfo& info) { SubmitExecution(info); } +void Scheduler::Flush() { + SubmitInfo info{}; + Flush(info); +} + void Scheduler::Finish() { // When finishing, we need to wait for the submission to have executed on the device. const u64 presubmit_tick = CurrentTick(); @@ -85,6 +90,12 @@ void Scheduler::Wait(u64 tick) { Flush(info); } master_semaphore.Wait(tick); + + // Only apply pending operations until the current tick. + while (!pending_ops.empty() && pending_ops.front().gpu_tick <= tick) { + pending_ops.front().callback(); + pending_ops.pop(); + } } void Scheduler::AllocateWorkerCommandBuffers() { diff --git a/src/video_core/renderer_vulkan/vk_scheduler.h b/src/video_core/renderer_vulkan/vk_scheduler.h index 7709e1d41..c30fc6e0e 100644 --- a/src/video_core/renderer_vulkan/vk_scheduler.h +++ b/src/video_core/renderer_vulkan/vk_scheduler.h @@ -307,6 +307,10 @@ public: /// and increments the scheduler timeline semaphore. void Flush(SubmitInfo& info); + /// Sends the current execution context to the GPU + /// and increments the scheduler timeline semaphore. + void Flush(); + /// Sends the current execution context to the GPU and waits for it to complete. void Finish();