blob: 6a1503c870eacef3374ab1287263f082785cb358 [file] [log] [blame]
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree.
*/
#include <executorch/backends/vulkan/runtime/vk_api/Fence.h>
namespace vkcompute {
namespace vkapi {
VulkanFence::VulkanFence()
: device_(VK_NULL_HANDLE), handle_(VK_NULL_HANDLE), waiting_(false) {}
VulkanFence::VulkanFence(VkDevice device)
: device_(device), handle_(VK_NULL_HANDLE), waiting_(VK_NULL_HANDLE) {
const VkFenceCreateInfo fence_create_info{
VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // sType
nullptr, // pNext
0u, // flags
};
VK_CHECK(vkCreateFence(device_, &fence_create_info, nullptr, &handle_));
}
VulkanFence::VulkanFence(VulkanFence&& other) noexcept
: device_(other.device_), handle_(other.handle_), waiting_(other.waiting_) {
other.handle_ = VK_NULL_HANDLE;
other.waiting_ = false;
}
VulkanFence& VulkanFence::operator=(VulkanFence&& other) noexcept {
device_ = other.device_;
handle_ = other.handle_;
waiting_ = other.waiting_;
other.device_ = VK_NULL_HANDLE;
other.handle_ = VK_NULL_HANDLE;
other.waiting_ = false;
return *this;
}
VulkanFence::~VulkanFence() {
if (VK_NULL_HANDLE == handle_) {
return;
}
vkDestroyFence(device_, handle_, nullptr);
}
void VulkanFence::wait() {
// if get_submit_handle() has not been called, then this will no-op
if (waiting_) {
VkResult fence_status = VK_NOT_READY;
// Run the wait in a loop to keep the CPU hot. A single call to
// vkWaitForFences with no timeout may cause the calling thread to be
// scheduled out.
do {
// The timeout (last) arg is in units of ns
fence_status = vkWaitForFences(device_, 1u, &handle_, VK_TRUE, 100000);
VK_CHECK_COND(
fence_status != VK_ERROR_DEVICE_LOST,
"Vulkan Fence: Device lost while waiting for fence!");
} while (fence_status != VK_SUCCESS);
VK_CHECK(vkResetFences(device_, 1u, &handle_));
waiting_ = false;
}
}
} // namespace vkapi
} // namespace vkcompute