1 /*
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 * All rights reserved.
4 *
5 * This source code is licensed under the BSD-style license found in the
6 * LICENSE file in the root directory of this source tree.
7 */
8
9 #include <executorch/backends/vulkan/runtime/vk_api/Fence.h>
10
11 namespace vkcompute {
12 namespace vkapi {
13
VulkanFence()14 VulkanFence::VulkanFence()
15 : device_(VK_NULL_HANDLE), handle_(VK_NULL_HANDLE), waiting_(false) {}
16
VulkanFence(VkDevice device)17 VulkanFence::VulkanFence(VkDevice device)
18 : device_(device), handle_(VK_NULL_HANDLE), waiting_(VK_NULL_HANDLE) {
19 const VkFenceCreateInfo fence_create_info{
20 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // sType
21 nullptr, // pNext
22 0u, // flags
23 };
24
25 VK_CHECK(vkCreateFence(device_, &fence_create_info, nullptr, &handle_));
26 }
27
VulkanFence(VulkanFence && other)28 VulkanFence::VulkanFence(VulkanFence&& other) noexcept
29 : device_(other.device_), handle_(other.handle_), waiting_(other.waiting_) {
30 other.handle_ = VK_NULL_HANDLE;
31 other.waiting_ = false;
32 }
33
operator =(VulkanFence && other)34 VulkanFence& VulkanFence::operator=(VulkanFence&& other) noexcept {
35 device_ = other.device_;
36 handle_ = other.handle_;
37 waiting_ = other.waiting_;
38
39 other.device_ = VK_NULL_HANDLE;
40 other.handle_ = VK_NULL_HANDLE;
41 other.waiting_ = false;
42
43 return *this;
44 }
45
~VulkanFence()46 VulkanFence::~VulkanFence() {
47 if (handle_ == VK_NULL_HANDLE) {
48 return;
49 }
50 vkDestroyFence(device_, handle_, nullptr);
51 }
52
wait()53 void VulkanFence::wait() {
54 // if get_submit_handle() has not been called, then this will no-op
55 if (waiting_) {
56 VkResult fence_status = VK_NOT_READY;
57 // Run the wait in a loop to keep the CPU hot. A single call to
58 // vkWaitForFences with no timeout may cause the calling thread to be
59 // scheduled out.
60 do {
61 // The timeout (last) arg is in units of ns
62 fence_status = vkWaitForFences(device_, 1u, &handle_, VK_TRUE, 100000);
63
64 VK_CHECK_COND(
65 fence_status != VK_ERROR_DEVICE_LOST,
66 "Vulkan Fence: Device lost while waiting for fence!");
67 } while (fence_status != VK_SUCCESS);
68
69 VK_CHECK(vkResetFences(device_, 1u, &handle_));
70
71 waiting_ = false;
72 }
73 }
74
75 } // namespace vkapi
76 } // namespace vkcompute
77