/* * 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 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 (handle_ == VK_NULL_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