// Copyright 2019-2022, Collabora, Ltd. // SPDX-License-Identifier: BSL-1.0 /*! * @file * @brief Independent @ref xrt_compositor_fence implementation. * @author Jakob Bornecrantz * @ingroup comp_util */ #include "xrt/xrt_config_os.h" #include "util/u_misc.h" #include "util/u_handles.h" #include "util/u_trace_marker.h" #include "util/comp_sync.h" #include #include #ifndef XRT_OS_WINDOWS #include #endif /* * * Structs. * */ /*! * A very simple implementation of a fence primitive. */ struct fence { struct xrt_compositor_fence base; struct vk_bundle *vk; VkFence fence; }; /* * * Fence member functions. * */ static xrt_result_t fence_wait(struct xrt_compositor_fence *xcf, uint64_t timeout) { COMP_TRACE_MARKER(); struct fence *f = (struct fence *)xcf; struct vk_bundle *vk = f->vk; // Count no handle as signled fence. if (f->fence == VK_NULL_HANDLE) { return XRT_SUCCESS; } VkResult ret = vk->vkWaitForFences(vk->device, 1, &f->fence, VK_TRUE, timeout); if (ret == VK_TIMEOUT) { return XRT_TIMEOUT; } if (ret != VK_SUCCESS) { VK_ERROR(vk, "vkWaitForFences: %s", vk_result_string(ret)); return XRT_ERROR_VULKAN; } return XRT_SUCCESS; } static void fence_destroy(struct xrt_compositor_fence *xcf) { COMP_TRACE_MARKER(); struct fence *f = (struct fence *)xcf; struct vk_bundle *vk = f->vk; if (f->fence != VK_NULL_HANDLE) { vk->vkDestroyFence(vk->device, f->fence, NULL); f->fence = VK_NULL_HANDLE; } free(f); } /* * * 'Exported' function. * */ xrt_result_t comp_fence_import(struct vk_bundle *vk, xrt_graphics_sync_handle_t handle, struct xrt_compositor_fence **out_xcf) { COMP_TRACE_MARKER(); VkFence fence = VK_NULL_HANDLE; VkResult ret = vk_create_fence_sync_from_native(vk, handle, &fence); if (ret != VK_SUCCESS) { return XRT_ERROR_VULKAN; } // Name for debugging. VK_NAME_FENCE(vk, fence, "Comp Sync"); struct fence *f = U_TYPED_CALLOC(struct fence); f->base.wait = fence_wait; f->base.destroy = fence_destroy; f->fence = fence; f->vk = vk; *out_xcf = &f->base; return XRT_SUCCESS; }