From 487ff4ed4d7d30911e930274deb2af26329aba89 Mon Sep 17 00:00:00 2001 From: CamilleLaVey Date: Sat, 8 Aug 2026 18:16:17 -0400 Subject: [PATCH] [TEST] Adjust introduction on shader write/read --- .../renderer_vulkan/vk_buffer_cache.cpp | 141 +++++++----------- .../renderer_vulkan/vk_buffer_cache.h | 4 + 2 files changed, 59 insertions(+), 86 deletions(-) diff --git a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp index 5c54267857..f713840d76 100644 --- a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp @@ -381,68 +381,65 @@ void BufferCacheRuntime::TryEnableUnifiedMemory(void* base, size_t size, device, base, size, hardware_buffers, hardware_buffer_window, hardware_buffer_base); if (!unified_memory->IsValid()) { unified_memory.reset(); + return; } + AcquireUnifiedWindowsFromForeign(); } -void BufferCacheRuntime::CopyToUnifiedMemory( - size_t window_index, VkBuffer src_buffer, - std::span copies) { - if (!unified_memory || src_buffer == VK_NULL_HANDLE || copies.empty() || - window_index >= unified_memory->GetWindowCount()) { +void BufferCacheRuntime::AcquireUnifiedWindowsFromForeign() { + if (!unified_memory->NeedsForeignOwnershipTransfer()) { return; } - const VkBuffer dst_buffer = unified_memory->GetWindowBuffer(window_index); - if (dst_buffer == VK_NULL_HANDLE) { - return; + boost::container::small_vector window_buffers; + const size_t window_count = unified_memory->GetWindowCount(); + for (size_t i = 0; i < window_count; ++i) { + const VkBuffer buffer = unified_memory->GetWindowBuffer(i); + if (buffer != VK_NULL_HANDLE) { + window_buffers.push_back(buffer); + } } - VkDeviceSize covered_begin = std::numeric_limits::max(); - VkDeviceSize covered_end = 0; - for (const VideoCommon::BufferCopy& copy : copies) { - covered_begin = (std::min)(covered_begin, static_cast(copy.dst_offset)); - covered_end = (std::max)(covered_end, - static_cast(copy.dst_offset + copy.size)); + if (window_buffers.empty()) { + return; } - - boost::container::small_vector vk_copies(copies.size()); - std::ranges::transform(copies, vk_copies.begin(), MakeBufferCopy); - - const bool foreign = unified_memory->NeedsForeignOwnershipTransfer(); const u32 queue_family = device.GetGraphicsFamily(); - scheduler.RequestOutsideRenderPassOperationContext(); - scheduler.Record([src_buffer, dst_buffer, vk_copies, foreign, queue_family, covered_begin, - covered_end](vk::CommandBuffer cmdbuf) { - if (foreign) { + scheduler.Record([window_buffers = std::move(window_buffers), + queue_family](vk::CommandBuffer cmdbuf) { + for (const VkBuffer buffer : window_buffers) { const VkBufferMemoryBarrier acquire{ .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, .pNext = nullptr, .srcAccessMask = 0, - .dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT, + .dstAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT, .srcQueueFamilyIndex = VK_QUEUE_FAMILY_FOREIGN_EXT, .dstQueueFamilyIndex = queue_family, - .buffer = dst_buffer, - .offset = covered_begin, - .size = covered_end - covered_begin, + .buffer = buffer, + .offset = 0, + .size = VK_WHOLE_SIZE, }; cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, - VK_PIPELINE_STAGE_TRANSFER_BIT, 0, acquire); + VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, acquire); } + }); +} + +void BufferCacheRuntime::CopyToUnifiedMemory( + size_t window_index, VkBuffer src_buffer, + std::span copies) { + if (!unified_memory || src_buffer == VK_NULL_HANDLE || copies.empty() || + window_index >= unified_memory->GetWindowCount()) { + return; + } + const VkBuffer dst_buffer = unified_memory->GetWindowBuffer(window_index); + if (dst_buffer == VK_NULL_HANDLE) { + return; + } + boost::container::small_vector vk_copies(copies.size()); + std::ranges::transform(copies, vk_copies.begin(), MakeBufferCopy); + + scheduler.RequestOutsideRenderPassOperationContext(); + scheduler.Record([src_buffer, dst_buffer, vk_copies](vk::CommandBuffer cmdbuf) { cmdbuf.CopyBuffer(src_buffer, dst_buffer, VideoCommon::FixSmallVectorADL(vk_copies)); - if (foreign) { - const VkBufferMemoryBarrier release{ - .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, - .pNext = nullptr, - .srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT, - .dstAccessMask = 0, - .srcQueueFamilyIndex = queue_family, - .dstQueueFamilyIndex = VK_QUEUE_FAMILY_FOREIGN_EXT, - .buffer = dst_buffer, - .offset = covered_begin, - .size = covered_end - covered_begin, - }; - cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, - VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, release); - } }); } @@ -457,54 +454,12 @@ void BufferCacheRuntime::CopyFromUnifiedMemory( if (src_buffer == VK_NULL_HANDLE) { return; } - VkDeviceSize covered_begin = std::numeric_limits::max(); - VkDeviceSize covered_end = 0; - for (const VideoCommon::BufferCopy& copy : copies) { - covered_begin = (std::min)(covered_begin, static_cast(copy.dst_offset)); - covered_end = (std::max)(covered_end, - static_cast(copy.dst_offset + copy.size)); - } - boost::container::small_vector vk_copies(copies.size()); std::ranges::transform(copies, vk_copies.begin(), MakeUnifiedUploadCopy); - const bool foreign = unified_memory->NeedsForeignOwnershipTransfer(); - const u32 queue_family = device.GetGraphicsFamily(); - scheduler.RequestOutsideRenderPassOperationContext(); - scheduler.Record([src_buffer, dst_buffer, vk_copies, foreign, queue_family, covered_begin, - covered_end](vk::CommandBuffer cmdbuf) { - if (foreign) { - const VkBufferMemoryBarrier acquire{ - .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, - .pNext = nullptr, - .srcAccessMask = 0, - .dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT, - .srcQueueFamilyIndex = VK_QUEUE_FAMILY_FOREIGN_EXT, - .dstQueueFamilyIndex = queue_family, - .buffer = src_buffer, - .offset = covered_begin, - .size = covered_end - covered_begin, - }; - cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, - VK_PIPELINE_STAGE_TRANSFER_BIT, 0, acquire); - } + scheduler.Record([src_buffer, dst_buffer, vk_copies](vk::CommandBuffer cmdbuf) { cmdbuf.CopyBuffer(src_buffer, dst_buffer, VideoCommon::FixSmallVectorADL(vk_copies)); - if (foreign) { - const VkBufferMemoryBarrier release{ - .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, - .pNext = nullptr, - .srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT, - .dstAccessMask = 0, - .srcQueueFamilyIndex = queue_family, - .dstQueueFamilyIndex = VK_QUEUE_FAMILY_FOREIGN_EXT, - .buffer = src_buffer, - .offset = covered_begin, - .size = covered_end - covered_begin, - }; - cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, - VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, release); - } }); } @@ -536,6 +491,20 @@ void BufferCacheRuntime::UnifiedMemoryHostBarrier() { }); } +void BufferCacheRuntime::UnifiedMemoryShaderWriteBarrier() { + static constexpr VkMemoryBarrier SHADER_WRITE_BARRIER{ + .sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER, + .pNext = nullptr, + .srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT, + .dstAccessMask = VK_ACCESS_HOST_READ_BIT, + }; + scheduler.RequestOutsideRenderPassOperationContext(); + scheduler.Record([](vk::CommandBuffer cmdbuf) { + cmdbuf.PipelineBarrier(vk::PIPELINE_STAGE_GRAPHICS_COMPUTE, VK_PIPELINE_STAGE_HOST_BIT, 0, + SHADER_WRITE_BARRIER); + }); +} + StagingBufferRef BufferCacheRuntime::UploadStagingBuffer(size_t size) { return staging_pool.Request(size, MemoryUsage::Upload); } diff --git a/src/video_core/renderer_vulkan/vk_buffer_cache.h b/src/video_core/renderer_vulkan/vk_buffer_cache.h index e1e4039bbb..bba84bd951 100644 --- a/src/video_core/renderer_vulkan/vk_buffer_cache.h +++ b/src/video_core/renderer_vulkan/vk_buffer_cache.h @@ -159,6 +159,8 @@ public: void UnifiedMemoryUploadBarrier(); + void UnifiedMemoryShaderWriteBarrier(); + u64 CurrentTick(); u64 KnownGpuTick(); @@ -253,6 +255,8 @@ private: VkFormat TexelBufferFormat(VideoCore::Surface::PixelFormat format) const; + void AcquireUnifiedWindowsFromForeign(); + void ReserveNullBuffer(); vk::Buffer CreateNullBuffer();