xref: /aosp_15_r20/external/executorch/backends/vulkan/runtime/vk_api/Fence.cpp (revision 523fa7a60841cd1ecfb9cc4201f1ca8b03ed023a)
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