From df5295ae8502890e76ac577ea4ade8f955aefae0 Mon Sep 17 00:00:00 2001 From: kd-11 Date: Sat, 12 Feb 2022 23:06:50 +0300 Subject: [PATCH] vk: Per work-queue scratch resources - Avoids parallel tasks from trampling over each other's data --- rpcs3/Emu/RSX/VK/VKGSRender.cpp | 4 ++-- rpcs3/Emu/RSX/VK/VKTexture.cpp | 12 +++++++++--- rpcs3/Emu/RSX/VK/VKTextureCache.cpp | 4 ++-- rpcs3/Emu/RSX/VK/vkutils/scratch.cpp | 11 ++++++++--- rpcs3/Emu/RSX/VK/vkutils/scratch.h | 6 ++++-- 5 files changed, 25 insertions(+), 12 deletions(-) diff --git a/rpcs3/Emu/RSX/VK/VKGSRender.cpp b/rpcs3/Emu/RSX/VK/VKGSRender.cpp index 959bf73e70..d79f2b86dd 100644 --- a/rpcs3/Emu/RSX/VK/VKGSRender.cpp +++ b/rpcs3/Emu/RSX/VK/VKGSRender.cpp @@ -1994,7 +1994,7 @@ void VKGSRender::load_program_env() if (vk::emulate_conditional_rendering()) { - auto predicate = m_cond_render_buffer ? m_cond_render_buffer->value : vk::get_scratch_buffer(4)->value; + auto predicate = m_cond_render_buffer ? m_cond_render_buffer->value : vk::get_scratch_buffer(*m_current_command_buffer, 4)->value; m_program->bind_buffer({ predicate, 0, 4 }, binding_table.conditional_render_predicate_slot, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, m_current_frame->descriptor_set); } @@ -2640,7 +2640,7 @@ void VKGSRender::begin_conditional_rendering(const std::vectoraspect() | dst->aspect()); // Initialize scratch memory - auto scratch_buf = vk::get_scratch_buffer(min_scratch_size); + auto scratch_buf = vk::get_scratch_buffer(cmd, min_scratch_size); for (u32 mip_level = 0; mip_level < mipmaps; ++mip_level) { @@ -552,7 +552,7 @@ namespace vk const auto dst_w = dst_rect.width(); const auto dst_h = dst_rect.height(); - auto scratch_buf = vk::get_scratch_buffer(std::max(src_w, dst_w) * std::max(src_h, dst_h) * 4); + auto scratch_buf = vk::get_scratch_buffer(cmd, std::max(src_w, dst_w) * std::max(src_h, dst_h) * 4); //1. Copy unscaled to typeless surface VkBufferImageCopy info{}; @@ -1014,7 +1014,13 @@ namespace vk scratch_buf_size += dst_image->width() * dst_image->height() * 5; } - scratch_buf = vk::get_scratch_buffer(scratch_buf_size); + // Must acquire scratch buffer owned by the processing command queue! + auto pdev = vk::get_current_renderer(); + const u32 queue_family = (image_setup_flags & vk::upload_contents_async) ? + pdev->get_transfer_queue_family() : + pdev->get_graphics_queue_family(); + + scratch_buf = vk::get_scratch_buffer(queue_family, scratch_buf_size); buffer_copies.reserve(subresource_layout.size()); } diff --git a/rpcs3/Emu/RSX/VK/VKTextureCache.cpp b/rpcs3/Emu/RSX/VK/VKTextureCache.cpp index e13807020f..af5da1e1b9 100644 --- a/rpcs3/Emu/RSX/VK/VKTextureCache.cpp +++ b/rpcs3/Emu/RSX/VK/VKTextureCache.cpp @@ -86,7 +86,7 @@ namespace vk const auto task_length = transfer_pitch * src_area.height(); const auto working_buffer_length = calculate_working_buffer_size(task_length, src->aspect()); - auto working_buffer = vk::get_scratch_buffer(working_buffer_length); + auto working_buffer = vk::get_scratch_buffer(cmd, working_buffer_length); auto final_mapping = vk::map_dma(valid_range.start, section_length); VkBufferImageCopy region = {}; @@ -358,7 +358,7 @@ namespace vk copy.imageSubresource = { src_image->aspect(), 0, 0, 1 }; const auto mem_length = src_w * src_h * dst_bpp; - auto scratch_buf = vk::get_scratch_buffer(mem_length); + auto scratch_buf = vk::get_scratch_buffer(cmd, mem_length); vkCmdCopyImageToBuffer(cmd, src_image->value, src_image->current_layout, scratch_buf->value, 1, ©); vk::insert_buffer_memory_barrier(cmd, scratch_buf->value, 0, mem_length, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, diff --git a/rpcs3/Emu/RSX/VK/vkutils/scratch.cpp b/rpcs3/Emu/RSX/VK/vkutils/scratch.cpp index 1401aa2d66..a07a50d59c 100644 --- a/rpcs3/Emu/RSX/VK/vkutils/scratch.cpp +++ b/rpcs3/Emu/RSX/VK/vkutils/scratch.cpp @@ -55,7 +55,7 @@ namespace vk return g_null_sampler; } - vk::image_view* null_image_view(vk::command_buffer& cmd, VkImageViewType type) + vk::image_view* null_image_view(const vk::command_buffer& cmd, VkImageViewType type) { if (auto found = g_null_image_views.find(type); found != g_null_image_views.end()) @@ -151,9 +151,9 @@ namespace vk return ptr.get(); } - vk::buffer* get_scratch_buffer(u64 min_required_size) + vk::buffer* get_scratch_buffer(u32 queue_family, u64 min_required_size) { - auto& scratch_buffer = g_scratch_buffers_pool[0 /*TODO: Replace with Queue Family ID*/].get_buf(); + auto& scratch_buffer = g_scratch_buffers_pool[queue_family].get_buf(); if (scratch_buffer && scratch_buffer->size() < min_required_size) { @@ -174,6 +174,11 @@ namespace vk return scratch_buffer.get(); } + vk::buffer* get_scratch_buffer(const vk::command_buffer& cmd, u64 min_required_size) + { + return get_scratch_buffer(cmd.get_queue_family(), min_required_size); + } + void clear_scratch_resources() { g_null_image_views.clear(); diff --git a/rpcs3/Emu/RSX/VK/vkutils/scratch.h b/rpcs3/Emu/RSX/VK/vkutils/scratch.h index 39a00604b4..4baed891b7 100644 --- a/rpcs3/Emu/RSX/VK/vkutils/scratch.h +++ b/rpcs3/Emu/RSX/VK/vkutils/scratch.h @@ -4,9 +4,11 @@ namespace vk { VkSampler null_sampler(); - image_view* null_image_view(command_buffer&, VkImageViewType type); + image_view* null_image_view(const command_buffer& cmd, VkImageViewType type); image* get_typeless_helper(VkFormat format, rsx::format_class format_class, u32 requested_width, u32 requested_height); - buffer* get_scratch_buffer(u64 min_required_size); + + buffer* get_scratch_buffer(u32 queue_family, u64 min_required_size); + buffer* get_scratch_buffer(const command_buffer& cmd, u64 min_required_size); void clear_scratch_resources(); }