VulkanBufferCache: Avoid adding barriers between multiple copies.
This commit is contained in:
		| @@ -853,12 +853,14 @@ void BufferCache<P>::CommitAsyncFlushesHigh() { | ||||
|     } | ||||
|     if constexpr (USE_MEMORY_MAPS) { | ||||
|         auto download_staging = runtime.DownloadStagingBuffer(total_size_bytes); | ||||
|         runtime.PreCopyBarrier(); | ||||
|         for (auto& [copy, buffer_id] : downloads) { | ||||
|             // Have in mind the staging buffer offset for the copy | ||||
|             copy.dst_offset += download_staging.offset; | ||||
|             const std::array copies{copy}; | ||||
|             runtime.CopyBuffer(download_staging.buffer, slot_buffers[buffer_id], copies); | ||||
|             runtime.CopyBuffer(download_staging.buffer, slot_buffers[buffer_id], copies, false); | ||||
|         } | ||||
|         runtime.PostCopyBarrier(); | ||||
|         runtime.Finish(); | ||||
|         for (const auto& [copy, buffer_id] : downloads) { | ||||
|             const Buffer& buffer = slot_buffers[buffer_id]; | ||||
|   | ||||
| @@ -146,7 +146,7 @@ void BufferCacheRuntime::Finish() { | ||||
| } | ||||
|  | ||||
| void BufferCacheRuntime::CopyBuffer(VkBuffer dst_buffer, VkBuffer src_buffer, | ||||
|                                     std::span<const VideoCommon::BufferCopy> copies) { | ||||
|                                     std::span<const VideoCommon::BufferCopy> copies, bool barrier) { | ||||
|     static constexpr VkMemoryBarrier READ_BARRIER{ | ||||
|         .sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER, | ||||
|         .pNext = nullptr, | ||||
| @@ -163,10 +163,42 @@ void BufferCacheRuntime::CopyBuffer(VkBuffer dst_buffer, VkBuffer src_buffer, | ||||
|     boost::container::small_vector<VkBufferCopy, 3> 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) { | ||||
|     scheduler.Record([src_buffer, dst_buffer, vk_copies, barrier](vk::CommandBuffer cmdbuf) { | ||||
|         if (barrier) { | ||||
|             cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, | ||||
|                                    VK_PIPELINE_STAGE_TRANSFER_BIT, 0, READ_BARRIER); | ||||
|         } | ||||
|         cmdbuf.CopyBuffer(src_buffer, dst_buffer, vk_copies); | ||||
|         if (barrier) { | ||||
|             cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, | ||||
|                                    VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, WRITE_BARRIER); | ||||
|         } | ||||
|     }); | ||||
| } | ||||
|  | ||||
| void BufferCacheRuntime::PreCopyBarrier() { | ||||
|     static constexpr VkMemoryBarrier READ_BARRIER{ | ||||
|         .sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER, | ||||
|         .pNext = nullptr, | ||||
|         .srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT, | ||||
|         .dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_TRANSFER_WRITE_BIT, | ||||
|     }; | ||||
|     scheduler.RequestOutsideRenderPassOperationContext(); | ||||
|     scheduler.Record([](vk::CommandBuffer cmdbuf) { | ||||
|         cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, | ||||
|                                0, READ_BARRIER); | ||||
|         cmdbuf.CopyBuffer(src_buffer, dst_buffer, vk_copies); | ||||
|     }); | ||||
| } | ||||
|  | ||||
| void BufferCacheRuntime::PostCopyBarrier() { | ||||
|     static constexpr VkMemoryBarrier WRITE_BARRIER{ | ||||
|         .sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER, | ||||
|         .pNext = nullptr, | ||||
|         .srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT, | ||||
|         .dstAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT, | ||||
|     }; | ||||
|     scheduler.RequestOutsideRenderPassOperationContext(); | ||||
|     scheduler.Record([](vk::CommandBuffer cmdbuf) { | ||||
|         cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, | ||||
|                                0, WRITE_BARRIER); | ||||
|     }); | ||||
|   | ||||
| @@ -69,8 +69,12 @@ public: | ||||
|  | ||||
|     [[nodiscard]] StagingBufferRef DownloadStagingBuffer(size_t size); | ||||
|  | ||||
|     void PreCopyBarrier(); | ||||
|  | ||||
|     void CopyBuffer(VkBuffer src_buffer, VkBuffer dst_buffer, | ||||
|                     std::span<const VideoCommon::BufferCopy> copies); | ||||
|                     std::span<const VideoCommon::BufferCopy> copies, bool barrier = true); | ||||
|  | ||||
|     void PostCopyBarrier(); | ||||
|  | ||||
|     void ClearBuffer(VkBuffer dest_buffer, u32 offset, size_t size, u32 value); | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Fernando Sahmkow
					Fernando Sahmkow