The open source OpenXR runtime
at mr/scanout-values 123 lines 2.1 kB view raw
1// Copyright 2019-2022, Collabora, Ltd. 2// SPDX-License-Identifier: BSL-1.0 3/*! 4 * @file 5 * @brief Independent @ref xrt_compositor_fence implementation. 6 * @author Jakob Bornecrantz <jakob@collabora.com> 7 * @ingroup comp_util 8 */ 9 10#include "xrt/xrt_config_os.h" 11 12#include "util/u_misc.h" 13#include "util/u_handles.h" 14#include "util/u_trace_marker.h" 15 16#include "util/comp_sync.h" 17 18#include <stdio.h> 19#include <stdlib.h> 20 21#ifndef XRT_OS_WINDOWS 22#include <unistd.h> 23#endif 24 25 26/* 27 * 28 * Structs. 29 * 30 */ 31 32/*! 33 * A very simple implementation of a fence primitive. 34 */ 35struct fence 36{ 37 struct xrt_compositor_fence base; 38 39 struct vk_bundle *vk; 40 41 VkFence fence; 42}; 43 44 45/* 46 * 47 * Fence member functions. 48 * 49 */ 50 51static xrt_result_t 52fence_wait(struct xrt_compositor_fence *xcf, uint64_t timeout) 53{ 54 COMP_TRACE_MARKER(); 55 56 struct fence *f = (struct fence *)xcf; 57 struct vk_bundle *vk = f->vk; 58 59 // Count no handle as signled fence. 60 if (f->fence == VK_NULL_HANDLE) { 61 return XRT_SUCCESS; 62 } 63 64 VkResult ret = vk->vkWaitForFences(vk->device, 1, &f->fence, VK_TRUE, timeout); 65 if (ret == VK_TIMEOUT) { 66 return XRT_TIMEOUT; 67 } 68 if (ret != VK_SUCCESS) { 69 VK_ERROR(vk, "vkWaitForFences: %s", vk_result_string(ret)); 70 return XRT_ERROR_VULKAN; 71 } 72 73 return XRT_SUCCESS; 74} 75 76static void 77fence_destroy(struct xrt_compositor_fence *xcf) 78{ 79 COMP_TRACE_MARKER(); 80 81 struct fence *f = (struct fence *)xcf; 82 struct vk_bundle *vk = f->vk; 83 84 if (f->fence != VK_NULL_HANDLE) { 85 vk->vkDestroyFence(vk->device, f->fence, NULL); 86 f->fence = VK_NULL_HANDLE; 87 } 88 89 free(f); 90} 91 92 93/* 94 * 95 * 'Exported' function. 96 * 97 */ 98 99xrt_result_t 100comp_fence_import(struct vk_bundle *vk, xrt_graphics_sync_handle_t handle, struct xrt_compositor_fence **out_xcf) 101{ 102 COMP_TRACE_MARKER(); 103 104 VkFence fence = VK_NULL_HANDLE; 105 106 VkResult ret = vk_create_fence_sync_from_native(vk, handle, &fence); 107 if (ret != VK_SUCCESS) { 108 return XRT_ERROR_VULKAN; 109 } 110 111 // Name for debugging. 112 VK_NAME_FENCE(vk, fence, "Comp Sync"); 113 114 struct fence *f = U_TYPED_CALLOC(struct fence); 115 f->base.wait = fence_wait; 116 f->base.destroy = fence_destroy; 117 f->fence = fence; 118 f->vk = vk; 119 120 *out_xcf = &f->base; 121 122 return XRT_SUCCESS; 123}