vk: Fix some regressions in synchronization2 behavior

This commit is contained in:
kd-11 2023-06-30 02:38:08 +03:00 committed by kd-11
parent 7ebabddfe0
commit c4acea6c82
3 changed files with 49 additions and 9 deletions

View File

@ -217,7 +217,7 @@ namespace vk
};
// Create event object for this transfer and queue signal op
dma_fence = std::make_unique<vk::event>(*m_device, sync_domain::any);
dma_fence = std::make_unique<vk::event>(*m_device, sync_domain::host);
dma_fence->signal(cmd,
{
.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,

View File

@ -209,13 +209,13 @@ namespace vk
}
event::event(const render_device& dev, sync_domain domain)
: m_device(&dev)
: m_device(&dev), m_domain(domain)
{
m_backend = dev.get_synchronization2_support()
? sync_backend::events_v2
: sync_backend::events_v1;
if (domain != sync_domain::gpu &&
if (domain == sync_domain::host &&
vk::get_driver_vendor() == vk::driver_vendor::AMD &&
vk::get_chip_family() < vk::chip_class::AMD_navi1x)
{
@ -280,10 +280,30 @@ namespace vk
return;
}
// Resolve the actual dependencies on a pipeline barrier
ensure(m_vk_event);
if (m_domain != sync_domain::host)
{
// As long as host is not involved, keep things consistent.
// The expectation is that this will be awaited using the gpu_wait function.
if (m_backend == sync_backend::events_v2) [[ likely ]]
{
m_device->_vkCmdSetEvent2KHR(cmd, m_vk_event, &dependency);
}
else
{
const auto dst_stages = v1_utils::gather_dst_stages(dependency);
vkCmdSetEvent(cmd, m_vk_event, dst_stages);
}
return;
}
// Host sync doesn't behave intuitively with events, so we use some workarounds.
// 1. Resolve the actual dependencies on a pipeline barrier.
resolve_dependencies(cmd, dependency);
// Signalling won't wait. The caller is responsible for setting up the dependencies correctly.
// 2. Signalling won't wait. The caller is responsible for setting up the dependencies correctly.
if (m_backend == sync_backend::events_v2)
{
// We need a memory barrier to keep AMDVLK from hanging
@ -293,6 +313,7 @@ namespace vk
.srcStageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT_KHR,
.srcAccessMask = VK_ACCESS_2_MEMORY_READ_BIT | VK_ACCESS_2_MEMORY_WRITE_BIT
};
// Empty dependency that does nothing
VkDependencyInfoKHR empty_dependency
{
@ -310,13 +331,19 @@ namespace vk
void event::host_signal() const
{
ensure(m_vk_event);
vkSetEvent(*m_device, m_vk_event);
if (m_backend != sync_backend::gpu_label) [[ likely ]]
{
ensure(m_vk_event);
vkSetEvent(*m_device, m_vk_event);
return;
}
m_label->set();
}
void event::gpu_wait(const command_buffer& cmd, const VkDependencyInfoKHR& dependency) const
{
ensure(m_vk_event);
ensure(m_vk_event && m_domain != sync_domain::host);
if (m_backend == sync_backend::events_v2) [[ likely ]]
{
@ -363,6 +390,15 @@ namespace vk
: pdev(&dev), m_count(count)
{}
gpu_label_pool::~gpu_label_pool()
{
if (m_mapped)
{
ensure(m_buffer);
m_buffer->unmap();
}
}
std::tuple<VkBuffer, u64, volatile u32*> gpu_label_pool::allocate()
{
if (!m_buffer || m_offset >= m_count)

View File

@ -14,7 +14,7 @@ namespace vk
enum class sync_domain
{
any = 0,
host = 0,
gpu = 1
};
@ -64,6 +64,7 @@ namespace vk
};
const vk::render_device* m_device = nullptr;
sync_domain m_domain = sync_domain::any;
sync_backend m_backend = sync_backend::events_v1;
// For events_v1 and events_v2
@ -106,6 +107,8 @@ namespace vk
{
public:
gpu_label_pool(const vk::render_device& dev, u32 count);
virtual ~gpu_label_pool();
std::tuple<VkBuffer, u64, volatile u32*> allocate();
private:
@ -137,6 +140,7 @@ namespace vk
void signal(const vk::command_buffer& cmd, const VkDependencyInfoKHR& dependency);
void reset() { *m_ptr = label_constants::reset_; }
void set() { *m_ptr = label_constants::set_; }
bool signaled() const { return label_constants::set_ == *m_ptr; }
};