From df36685c9bc8b4ec8d990aba8ee0314eda8e0d2c Mon Sep 17 00:00:00 2001 From: CamilleLaVey Date: Thu, 1 Oct 2026 02:01:24 -0400 Subject: [PATCH] Port UMA part 3 --- src/video_core/buffer_cache/buffer_cache.h | 17 +++++++++++++++-- .../renderer_vulkan/vk_buffer_cache.cpp | 8 ++++++++ .../renderer_vulkan/vk_buffer_cache.h | 2 ++ src/video_core/renderer_vulkan/vk_scheduler.cpp | 12 ++++++++++++ 4 files changed, 37 insertions(+), 2 deletions(-) diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h index 734ec5e0f3..00d632744b 100644 --- a/src/video_core/buffer_cache/buffer_cache.h +++ b/src/video_core/buffer_cache/buffer_cache.h @@ -327,6 +327,7 @@ std::pair BufferCache

::ObtainCPUBuffer( default: break; } + buffer.MarkUsage(buffer.Offset(device_addr), size); switch (post_op) { case ObtainBufferOperation::MarkAsWritten: @@ -394,8 +395,9 @@ void BufferCache

::CommitDrawWrites() { } const u64 pass = runtime.RenderPassSerial(); for (const DrawWrite& write : draw_writes) { - slot_buffers[write.buffer_id].MarkDrawWrite(pass, draw_wfi, write.device_addr, - write.size, write.feedback); + Buffer& buffer = slot_buffers[write.buffer_id]; + buffer.setWriteTick(runtime.CurrentTick()); + buffer.MarkDrawWrite(pass, draw_wfi, write.device_addr, write.size, write.feedback); } runtime.MarkRenderPassWrites(); } @@ -956,6 +958,7 @@ void BufferCache

::BindHostDrawIndirectBuffers() { Buffer& buffer = slot_buffers[binding.buffer_id]; TouchBuffer(buffer, binding.buffer_id); SynchronizeBuffer(buffer, binding.device_addr, binding.size); + buffer.MarkUsage(buffer.Offset(binding.device_addr), binding.size); }; if (current_draw_indirect->include_count) { bind_buffer(channel_state->count_buffer_binding); @@ -1989,6 +1992,16 @@ void BufferCache

::DownloadBufferMemory(Buffer& buffer, DAddr device_addr, u64 } if constexpr (USE_MEMORY_MAPS) { + if constexpr (requires { runtime.DirectDownloadSpan(buffer); }) { + const std::span direct = runtime.DirectDownloadSpan(buffer); + if (!direct.empty()) { + for (const BufferCopy& copy : copies) { + device_memory.WriteBlockUnsafe(buffer.CpuAddr() + copy.src_offset, + direct.data() + copy.src_offset, copy.size); + } + return; + } + } auto download_staging = runtime.DownloadStagingBuffer(total_size_bytes); const u8* const mapped_memory = download_staging.mapped_span.data(); const std::span copies_span(copies.data(), copies.data() + copies.size()); diff --git a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp index f35ee502ce..20db32b52a 100644 --- a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp @@ -511,6 +511,14 @@ bool BufferCacheRuntime::CanReorderUpload(const Buffer& buffer, return can_use_upload_cmdbuf; } +std::span BufferCacheRuntime::DirectDownloadSpan(Buffer& buffer) { + const std::span mapping = buffer.CoherentMapping(); + if (!mapping.empty()) { + scheduler.Wait((std::max)(buffer.getWriteTick(), buffer.LastUploadTick())); + } + return mapping; +} + std::span BufferCacheRuntime::DirectUploadSpan( Buffer& buffer, std::span copies) { const std::span mapping = buffer.CoherentMapping(); diff --git a/src/video_core/renderer_vulkan/vk_buffer_cache.h b/src/video_core/renderer_vulkan/vk_buffer_cache.h index d96bd3783a..c963990385 100644 --- a/src/video_core/renderer_vulkan/vk_buffer_cache.h +++ b/src/video_core/renderer_vulkan/vk_buffer_cache.h @@ -149,6 +149,8 @@ public: bool CanReorderUpload(const Buffer& buffer, std::span copies); + [[nodiscard]] std::span DirectDownloadSpan(Buffer& buffer); + [[nodiscard]] std::span DirectUploadSpan(Buffer& buffer, std::span copies); diff --git a/src/video_core/renderer_vulkan/vk_scheduler.cpp b/src/video_core/renderer_vulkan/vk_scheduler.cpp index cde7da2bcb..91aac1a51d 100644 --- a/src/video_core/renderer_vulkan/vk_scheduler.cpp +++ b/src/video_core/renderer_vulkan/vk_scheduler.cpp @@ -32,6 +32,15 @@ namespace Vulkan { namespace { constexpr size_t DEPTH_VIEW = 8; +constexpr VkMemoryBarrier2 HOST_READ_BARRIER{ + .sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER_2, + .pNext = nullptr, + .srcStageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT, + .srcAccessMask = VK_ACCESS_2_MEMORY_WRITE_BIT, + .dstStageMask = VK_PIPELINE_STAGE_2_HOST_BIT, + .dstAccessMask = VK_ACCESS_2_HOST_READ_BIT, +}; + struct BeginRenderingCommand { void operator()(vk::CommandBuffer cmdbuf, vk::CommandBuffer) const { BeginRendering(cmdbuf, attachments); @@ -477,6 +486,9 @@ u64 Scheduler::SubmitExecution(VkSemaphore signal_semaphore, VkSemaphore wait_se this](vk::CommandBuffer cmdbuf, vk::CommandBuffer upload_cmdbuf) { upload_cmdbuf.PipelineBarrier(upload_write_barrier); upload_cmdbuf.End(); + if (device.IsUMA()) { + cmdbuf.PipelineBarrier(HOST_READ_BARRIER); + } cmdbuf.End(); if (on_submit) {