mirror of
https://gitlab.freedesktop.org/monado/monado.git
synced 2024-12-29 11:06:18 +00:00
c/util: Impelement xrt_compositor_semaphore interfaces
This commit is contained in:
parent
851224123e
commit
8a9a8aeeba
|
@ -67,6 +67,8 @@ if(XRT_HAVE_VULKAN)
|
||||||
comp_util STATIC
|
comp_util STATIC
|
||||||
util/comp_base.h
|
util/comp_base.h
|
||||||
util/comp_base.c
|
util/comp_base.c
|
||||||
|
util/comp_semaphore.h
|
||||||
|
util/comp_semaphore.c
|
||||||
util/comp_swapchain.h
|
util/comp_swapchain.h
|
||||||
util/comp_swapchain.c
|
util/comp_swapchain.c
|
||||||
util/comp_sync.h
|
util/comp_sync.h
|
||||||
|
|
|
@ -39,6 +39,8 @@ compositor_srcs = [
|
||||||
'render/comp_util.c',
|
'render/comp_util.c',
|
||||||
'util/comp_base.h',
|
'util/comp_base.h',
|
||||||
'util/comp_base.c',
|
'util/comp_base.c',
|
||||||
|
'util/comp_semaphore.h',
|
||||||
|
'util/comp_semaphore.c',
|
||||||
'util/comp_swapchain.h',
|
'util/comp_swapchain.h',
|
||||||
'util/comp_swapchain.c',
|
'util/comp_swapchain.c',
|
||||||
'util/comp_sync.h',
|
'util/comp_sync.h',
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2019-2021, Collabora, Ltd.
|
// Copyright 2019-2022, Collabora, Ltd.
|
||||||
// SPDX-License-Identifier: BSL-1.0
|
// SPDX-License-Identifier: BSL-1.0
|
||||||
/*!
|
/*!
|
||||||
* @file
|
* @file
|
||||||
|
@ -11,6 +11,7 @@
|
||||||
#include "util/u_trace_marker.h"
|
#include "util/u_trace_marker.h"
|
||||||
|
|
||||||
#include "util/comp_base.h"
|
#include "util/comp_base.h"
|
||||||
|
#include "util/comp_semaphore.h"
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -76,6 +77,16 @@ base_import_fence(struct xrt_compositor *xc, xrt_graphics_sync_handle_t handle,
|
||||||
return comp_fence_import(&cb->vk, handle, out_xcf);
|
return comp_fence_import(&cb->vk, handle, out_xcf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static xrt_result_t
|
||||||
|
base_create_semaphore(struct xrt_compositor *xc,
|
||||||
|
xrt_graphics_sync_handle_t *out_handle,
|
||||||
|
struct xrt_compositor_semaphore **out_xcsem)
|
||||||
|
{
|
||||||
|
struct comp_base *cb = comp_base(xc);
|
||||||
|
|
||||||
|
return comp_semaphore_create(&cb->vk, out_handle, out_xcsem);
|
||||||
|
}
|
||||||
|
|
||||||
static xrt_result_t
|
static xrt_result_t
|
||||||
base_layer_begin(struct xrt_compositor *xc,
|
base_layer_begin(struct xrt_compositor *xc,
|
||||||
int64_t frame_id,
|
int64_t frame_id,
|
||||||
|
@ -234,6 +245,7 @@ comp_base_init(struct comp_base *cb)
|
||||||
{
|
{
|
||||||
cb->base.base.create_swapchain = base_create_swapchain;
|
cb->base.base.create_swapchain = base_create_swapchain;
|
||||||
cb->base.base.import_swapchain = base_import_swapchain;
|
cb->base.base.import_swapchain = base_import_swapchain;
|
||||||
|
cb->base.base.create_semaphore = base_create_semaphore;
|
||||||
cb->base.base.import_fence = base_import_fence;
|
cb->base.base.import_fence = base_import_fence;
|
||||||
cb->base.base.layer_begin = base_layer_begin;
|
cb->base.base.layer_begin = base_layer_begin;
|
||||||
cb->base.base.layer_stereo_projection = base_layer_stereo_projection;
|
cb->base.base.layer_stereo_projection = base_layer_stereo_projection;
|
||||||
|
|
172
src/xrt/compositor/util/comp_semaphore.c
Normal file
172
src/xrt/compositor/util/comp_semaphore.c
Normal file
|
@ -0,0 +1,172 @@
|
||||||
|
// Copyright 2019-2022, Collabora, Ltd.
|
||||||
|
// SPDX-License-Identifier: BSL-1.0
|
||||||
|
/*!
|
||||||
|
* @file
|
||||||
|
* @brief Independent semaphore implementation.
|
||||||
|
* @author Jakob Bornecrantz <jakob@collabora.com>
|
||||||
|
* @ingroup comp_util
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "util/comp_semaphore.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Member functions.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef VK_KHR_timeline_semaphore
|
||||||
|
static xrt_result_t
|
||||||
|
semaphore_wait(struct xrt_compositor_semaphore *xcsem, uint64_t value, uint64_t timeout_ns)
|
||||||
|
{
|
||||||
|
struct comp_semaphore *csem = comp_semaphore(xcsem);
|
||||||
|
struct vk_bundle *vk = csem->vk;
|
||||||
|
VkResult ret;
|
||||||
|
|
||||||
|
VkSemaphoreWaitInfo wait_info = {
|
||||||
|
.sType = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO,
|
||||||
|
.flags = 0,
|
||||||
|
.semaphoreCount = 1,
|
||||||
|
.pSemaphores = &csem->semaphore,
|
||||||
|
.pValues = &value,
|
||||||
|
};
|
||||||
|
|
||||||
|
ret = vk->vkWaitSemaphores( //
|
||||||
|
vk->device, // device
|
||||||
|
&wait_info, // pWaitInfo
|
||||||
|
timeout_ns); // timeout
|
||||||
|
if (ret == VK_TIMEOUT) {
|
||||||
|
return XRT_TIMEOUT;
|
||||||
|
}
|
||||||
|
if (ret != VK_SUCCESS) {
|
||||||
|
VK_ERROR(vk, "vkWaitSemaphores: %s", vk_result_string(ret));
|
||||||
|
return XRT_ERROR_VULKAN;
|
||||||
|
}
|
||||||
|
|
||||||
|
return XRT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
semaphore_destroy(struct xrt_compositor_semaphore *xcsem)
|
||||||
|
{
|
||||||
|
struct comp_semaphore *csem = comp_semaphore(xcsem);
|
||||||
|
struct vk_bundle *vk = csem->vk;
|
||||||
|
|
||||||
|
vk->vkDestroySemaphore( //
|
||||||
|
vk->device, // device
|
||||||
|
csem->semaphore, // semaphore
|
||||||
|
NULL); // pAllocator
|
||||||
|
|
||||||
|
free(csem);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* 'Exported' functions.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
xrt_result_t
|
||||||
|
comp_semaphore_create(struct vk_bundle *vk,
|
||||||
|
xrt_graphics_sync_handle_t *out_handle,
|
||||||
|
struct xrt_compositor_semaphore **out_xcsem)
|
||||||
|
{
|
||||||
|
#ifdef VK_KHR_timeline_semaphore
|
||||||
|
VkResult ret;
|
||||||
|
|
||||||
|
if (!vk->features.timeline_semaphore) {
|
||||||
|
return XRT_ERROR_VULKAN;
|
||||||
|
}
|
||||||
|
|
||||||
|
VkExternalSemaphoreHandleTypeFlags handle_type = 0;
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(XRT_GRAPHICS_SYNC_HANDLE_IS_FD)
|
||||||
|
if (!vk->external.timeline_semaphore_opaque_fd) {
|
||||||
|
VK_ERROR(vk, "External timeline semaphore opaque fd not supported!");
|
||||||
|
return XRT_ERROR_VULKAN;
|
||||||
|
} else {
|
||||||
|
handle_type = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT;
|
||||||
|
}
|
||||||
|
#elif defined(XRT_GRAPHICS_SYNC_HANDLE_IS_WIN32_HANDLE)
|
||||||
|
if (!vk->external.timeline_semaphore_win32_handle) {
|
||||||
|
VK_ERROR(vk, "External timeline semaphore win32 handle not supported!");
|
||||||
|
return XRT_ERROR_VULKAN;
|
||||||
|
} else {
|
||||||
|
handle_type = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#error "Need to port semaphore creation code."
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
VkExportSemaphoreCreateInfo export_info = {
|
||||||
|
.sType = VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO,
|
||||||
|
.handleTypes = handle_type,
|
||||||
|
};
|
||||||
|
|
||||||
|
VkSemaphoreTypeCreateInfo type_info = {
|
||||||
|
.sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO,
|
||||||
|
.pNext = &export_info,
|
||||||
|
.semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE,
|
||||||
|
.initialValue = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
VkSemaphoreCreateInfo semaphore_create_info = {
|
||||||
|
.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
|
||||||
|
.pNext = &type_info,
|
||||||
|
.flags = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
VkSemaphore semaphore = VK_NULL_HANDLE;
|
||||||
|
ret = vk->vkCreateSemaphore( //
|
||||||
|
vk->device, // dev
|
||||||
|
&semaphore_create_info, // pCreateInfo
|
||||||
|
NULL, // pAllocator
|
||||||
|
&semaphore); // pSemaphore
|
||||||
|
if (ret != VK_SUCCESS) {
|
||||||
|
VK_ERROR(vk, "vkCreateSemaphore: %s", vk_result_string(ret));
|
||||||
|
return XRT_ERROR_VULKAN;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(XRT_GRAPHICS_SYNC_HANDLE_IS_FD)
|
||||||
|
VkSemaphoreGetFdInfoKHR get_fd_info = {
|
||||||
|
.sType = VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR,
|
||||||
|
.semaphore = semaphore,
|
||||||
|
.handleType = handle_type,
|
||||||
|
};
|
||||||
|
|
||||||
|
ret = vk->vkGetSemaphoreFdKHR(vk->device, &get_fd_info, out_handle);
|
||||||
|
if (ret != VK_SUCCESS) {
|
||||||
|
VK_ERROR(vk, "vkGetSemaphoreFdKHR: %s", vk_result_string(ret));
|
||||||
|
vk->vkDestroySemaphore(vk->device, semaphore, NULL);
|
||||||
|
return XRT_ERROR_VULKAN;
|
||||||
|
}
|
||||||
|
#elif defined(XRT_GRAPHICS_SYNC_HANDLE_IS_WIN32_HANDLE)
|
||||||
|
#error "No windows port"
|
||||||
|
#else
|
||||||
|
#error "Need to port semaphore creation code."
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
struct comp_semaphore *csem = U_TYPED_CALLOC(struct comp_semaphore);
|
||||||
|
|
||||||
|
csem->base.reference.count = 1;
|
||||||
|
csem->base.destroy = semaphore_destroy;
|
||||||
|
csem->base.wait = semaphore_wait;
|
||||||
|
csem->semaphore = semaphore;
|
||||||
|
csem->vk = vk;
|
||||||
|
|
||||||
|
*out_xcsem = &csem->base;
|
||||||
|
|
||||||
|
return XRT_SUCCESS;
|
||||||
|
#else
|
||||||
|
// How did you even get here?
|
||||||
|
VK_ERROR(vk, "No compile time support for VK_KHR_timeline_semaphore!");
|
||||||
|
return XRT_ERROR_VULKAN;
|
||||||
|
#endif
|
||||||
|
}
|
76
src/xrt/compositor/util/comp_semaphore.h
Normal file
76
src/xrt/compositor/util/comp_semaphore.h
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
// Copyright 2019-2022, Collabora, Ltd.
|
||||||
|
// SPDX-License-Identifier: BSL-1.0
|
||||||
|
/*!
|
||||||
|
* @file
|
||||||
|
* @brief Independent semaphore implementation.
|
||||||
|
* @author Jakob Bornecrantz <jakob@collabora.com>
|
||||||
|
* @ingroup comp_util
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "xrt/xrt_compositor.h"
|
||||||
|
#include "vk/vk_helpers.h"
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* A simple implementation of the xrt_compositor_semaphore interface.
|
||||||
|
*
|
||||||
|
* @ingroup comp_util
|
||||||
|
* @implements xrt_compositor_swapchain
|
||||||
|
* @see comp_compositor
|
||||||
|
*/
|
||||||
|
struct comp_semaphore
|
||||||
|
{
|
||||||
|
struct xrt_compositor_semaphore base;
|
||||||
|
|
||||||
|
struct vk_bundle *vk;
|
||||||
|
|
||||||
|
VkSemaphore semaphore;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Helper functions.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Convenience function to convert a xrt_compositor_semaphore to a comp_semaphore.
|
||||||
|
*
|
||||||
|
* @ingroup comp_util
|
||||||
|
* @private @memberof comp_semaphore
|
||||||
|
*/
|
||||||
|
static inline struct comp_semaphore *
|
||||||
|
comp_semaphore(struct xrt_compositor_semaphore *xcsem)
|
||||||
|
{
|
||||||
|
return (struct comp_semaphore *)xcsem;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* 'Exported' functions.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Creates a @ref comp_semaphore, used to implement compositor functionality.
|
||||||
|
*
|
||||||
|
* @ingroup comp_util
|
||||||
|
*/
|
||||||
|
xrt_result_t
|
||||||
|
comp_semaphore_create(struct vk_bundle *vk,
|
||||||
|
xrt_graphics_sync_handle_t *out_handle,
|
||||||
|
struct xrt_compositor_semaphore **out_xcsem);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
Loading…
Reference in a new issue