vk: Per work-queue scratch resources

- Avoids parallel tasks from trampling over each other's data
This commit is contained in:
kd-11 2022-02-12 23:06:50 +03:00 committed by kd-11
parent c8ad8b18bb
commit df5295ae85
5 changed files with 25 additions and 12 deletions

View file

@ -1994,7 +1994,7 @@ void VKGSRender::load_program_env()
if (vk::emulate_conditional_rendering()) 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); 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::vector<rsx::reports::occ
} }
} }
auto scratch = vk::get_scratch_buffer(OCCLUSION_MAX_POOL_SIZE * 4); auto scratch = vk::get_scratch_buffer(*m_current_command_buffer, OCCLUSION_MAX_POOL_SIZE * 4);
u32 dst_offset = 0; u32 dst_offset = 0;
usz first = 0; usz first = 0;
usz last; usz last;

View file

@ -347,7 +347,7 @@ namespace vk
const auto min_scratch_size = calculate_working_buffer_size(src_length, src->aspect() | dst->aspect()); const auto min_scratch_size = calculate_working_buffer_size(src_length, src->aspect() | dst->aspect());
// Initialize scratch memory // 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) 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_w = dst_rect.width();
const auto dst_h = dst_rect.height(); 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 //1. Copy unscaled to typeless surface
VkBufferImageCopy info{}; VkBufferImageCopy info{};
@ -1014,7 +1014,13 @@ namespace vk
scratch_buf_size += dst_image->width() * dst_image->height() * 5; 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()); buffer_copies.reserve(subresource_layout.size());
} }

View file

@ -86,7 +86,7 @@ namespace vk
const auto task_length = transfer_pitch * src_area.height(); const auto task_length = transfer_pitch * src_area.height();
const auto working_buffer_length = calculate_working_buffer_size(task_length, src->aspect()); 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); auto final_mapping = vk::map_dma(valid_range.start, section_length);
VkBufferImageCopy region = {}; VkBufferImageCopy region = {};
@ -358,7 +358,7 @@ namespace vk
copy.imageSubresource = { src_image->aspect(), 0, 0, 1 }; copy.imageSubresource = { src_image->aspect(), 0, 0, 1 };
const auto mem_length = src_w * src_h * dst_bpp; 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, &copy); vkCmdCopyImageToBuffer(cmd, src_image->value, src_image->current_layout, scratch_buf->value, 1, &copy);
vk::insert_buffer_memory_barrier(cmd, scratch_buf->value, 0, mem_length, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, vk::insert_buffer_memory_barrier(cmd, scratch_buf->value, 0, mem_length, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,

View file

@ -55,7 +55,7 @@ namespace vk
return g_null_sampler; 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); if (auto found = g_null_image_views.find(type);
found != g_null_image_views.end()) found != g_null_image_views.end())
@ -151,9 +151,9 @@ namespace vk
return ptr.get(); 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) if (scratch_buffer && scratch_buffer->size() < min_required_size)
{ {
@ -174,6 +174,11 @@ namespace vk
return scratch_buffer.get(); 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() void clear_scratch_resources()
{ {
g_null_image_views.clear(); g_null_image_views.clear();

View file

@ -4,9 +4,11 @@
namespace vk namespace vk
{ {
VkSampler null_sampler(); 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); 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(); void clear_scratch_resources();
} }