2019-03-18 05:52:32 +00:00
|
|
|
// Copyright 2018-2019, Collabora, Ltd.
|
|
|
|
// SPDX-License-Identifier: BSL-1.0
|
|
|
|
/*!
|
|
|
|
* @file
|
|
|
|
* @brief Holds swapchain related functions.
|
|
|
|
* @author Jakob Bornecrantz <jakob@collabora.com>
|
|
|
|
* @ingroup oxr_main
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
#include "xrt/xrt_gfx_xlib.h"
|
2019-03-21 20:19:52 +00:00
|
|
|
|
2019-03-18 05:52:32 +00:00
|
|
|
#include "util/u_debug.h"
|
2019-03-21 20:19:52 +00:00
|
|
|
#include "util/u_misc.h"
|
2019-03-18 05:52:32 +00:00
|
|
|
|
|
|
|
#include "oxr_objects.h"
|
|
|
|
#include "oxr_logger.h"
|
2019-04-05 19:18:03 +00:00
|
|
|
#include "oxr_handle.h"
|
2019-03-18 05:52:32 +00:00
|
|
|
|
|
|
|
|
|
|
|
static XrResult
|
|
|
|
oxr_swapchain_acquire_image(struct oxr_logger *log,
|
|
|
|
struct oxr_swapchain *sc,
|
|
|
|
const XrSwapchainImageAcquireInfo *acquireInfo,
|
|
|
|
uint32_t *out_index)
|
|
|
|
{
|
|
|
|
uint32_t index;
|
2020-05-30 16:01:00 +00:00
|
|
|
if (sc->acquired.num >= sc->swapchain->num_images) {
|
2019-03-18 05:52:32 +00:00
|
|
|
return oxr_error(log, XR_ERROR_CALL_ORDER_INVALID,
|
2020-05-30 16:01:00 +00:00
|
|
|
" all images have been acquired");
|
2019-03-18 05:52:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
struct xrt_swapchain *xsc = (struct xrt_swapchain *)sc->swapchain;
|
|
|
|
if (!xsc->acquire_image(xsc, &index)) {
|
|
|
|
return oxr_error(log, XR_ERROR_RUNTIME_FAILURE,
|
|
|
|
" call to xsc->acquire_image failed");
|
|
|
|
}
|
|
|
|
|
2020-05-30 16:01:00 +00:00
|
|
|
if (sc->images[index].state != OXR_IMAGE_STATE_READY) {
|
|
|
|
return oxr_error(
|
|
|
|
log, XR_ERROR_RUNTIME_FAILURE,
|
|
|
|
"Internal acquire call returned non-ready image.");
|
|
|
|
}
|
|
|
|
|
|
|
|
sc->acquired.num++;
|
|
|
|
u_index_fifo_push(&sc->acquired.fifo, index);
|
|
|
|
sc->images[index].state = OXR_IMAGE_STATE_ACQUIRED;
|
2019-06-28 15:03:31 +00:00
|
|
|
|
|
|
|
// If the compositor is resuing the image,
|
|
|
|
// mark it as invalid to use in xrEndFrame.
|
2020-05-30 16:01:00 +00:00
|
|
|
if (sc->released.index == (int)index) {
|
|
|
|
sc->released.yes = false;
|
|
|
|
sc->released.index = -1;
|
2019-06-28 15:03:31 +00:00
|
|
|
}
|
|
|
|
|
2019-03-18 05:52:32 +00:00
|
|
|
*out_index = index;
|
|
|
|
|
2019-09-26 20:25:05 +00:00
|
|
|
return oxr_session_success_result(sc->sess);
|
2019-03-18 05:52:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static XrResult
|
|
|
|
oxr_swapchain_wait_image(struct oxr_logger *log,
|
|
|
|
struct oxr_swapchain *sc,
|
|
|
|
const XrSwapchainImageWaitInfo *waitInfo)
|
|
|
|
{
|
2020-05-30 16:01:00 +00:00
|
|
|
if (sc->waited.yes) {
|
|
|
|
return oxr_error(
|
|
|
|
log, XR_ERROR_CALL_ORDER_INVALID,
|
|
|
|
" swapchain has already been waited, call release");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (u_index_fifo_is_empty(&sc->acquired.fifo)) {
|
2019-03-18 05:52:32 +00:00
|
|
|
return oxr_error(log, XR_ERROR_CALL_ORDER_INVALID,
|
|
|
|
" no image acquired");
|
|
|
|
}
|
|
|
|
|
2020-05-30 16:01:00 +00:00
|
|
|
uint32_t index;
|
|
|
|
u_index_fifo_pop(&sc->acquired.fifo, &index);
|
|
|
|
|
2019-03-18 05:52:32 +00:00
|
|
|
struct xrt_swapchain *xsc = (struct xrt_swapchain *)sc->swapchain;
|
2020-05-30 16:01:00 +00:00
|
|
|
if (!xsc->wait_image(xsc, waitInfo->timeout, index)) {
|
2019-03-18 05:52:32 +00:00
|
|
|
return oxr_error(log, XR_ERROR_RUNTIME_FAILURE,
|
|
|
|
" call to xsc->wait_image failed");
|
|
|
|
}
|
|
|
|
|
2020-05-30 16:01:00 +00:00
|
|
|
// The app can only wait on one image.
|
|
|
|
sc->waited.yes = true;
|
|
|
|
sc->waited.index = index;
|
|
|
|
sc->images[index].state = OXR_IMAGE_STATE_WAITED;
|
|
|
|
|
2019-09-26 20:25:05 +00:00
|
|
|
return oxr_session_success_result(sc->sess);
|
2019-03-18 05:52:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static XrResult
|
|
|
|
oxr_swapchain_release_image(struct oxr_logger *log,
|
|
|
|
struct oxr_swapchain *sc,
|
|
|
|
const XrSwapchainImageReleaseInfo *releaseInfo)
|
|
|
|
{
|
2020-05-30 16:01:00 +00:00
|
|
|
if (!sc->waited.yes) {
|
2019-03-18 05:52:32 +00:00
|
|
|
return oxr_error(log, XR_ERROR_CALL_ORDER_INVALID,
|
2020-05-30 16:01:00 +00:00
|
|
|
" no swapchain images waited on");
|
2019-03-18 05:52:32 +00:00
|
|
|
}
|
|
|
|
|
2020-05-30 16:01:00 +00:00
|
|
|
sc->waited.yes = false;
|
|
|
|
uint32_t index = sc->waited.index;
|
|
|
|
|
2019-03-18 05:52:32 +00:00
|
|
|
struct xrt_swapchain *xsc = (struct xrt_swapchain *)sc->swapchain;
|
2020-05-30 16:01:00 +00:00
|
|
|
if (!xsc->release_image(xsc, index)) {
|
2019-03-18 05:52:32 +00:00
|
|
|
return oxr_error(log, XR_ERROR_RUNTIME_FAILURE,
|
|
|
|
" call to xsc->release_image failed");
|
|
|
|
}
|
2019-06-28 15:03:31 +00:00
|
|
|
|
2020-05-30 16:01:00 +00:00
|
|
|
// Only decerement here.
|
|
|
|
sc->acquired.num--;
|
|
|
|
|
2019-06-28 15:03:31 +00:00
|
|
|
// Overwrite the old released image, with new.
|
2020-05-30 16:01:00 +00:00
|
|
|
sc->released.yes = true;
|
|
|
|
sc->released.index = index;
|
|
|
|
sc->images[index].state = OXR_IMAGE_STATE_READY;
|
2019-03-18 05:52:32 +00:00
|
|
|
|
2019-09-26 20:25:05 +00:00
|
|
|
return oxr_session_success_result(sc->sess);
|
2019-03-18 05:52:32 +00:00
|
|
|
}
|
|
|
|
|
2019-04-05 19:18:03 +00:00
|
|
|
static XrResult
|
|
|
|
oxr_swapchain_destroy(struct oxr_logger *log, struct oxr_handle_base *hb)
|
|
|
|
{
|
|
|
|
struct oxr_swapchain *sc = (struct oxr_swapchain *)hb;
|
|
|
|
|
2019-11-13 20:53:16 +00:00
|
|
|
XrResult ret = sc->destroy(log, sc);
|
|
|
|
free(sc);
|
|
|
|
return ret;
|
2019-04-05 19:18:03 +00:00
|
|
|
}
|
|
|
|
|
2020-05-27 18:53:22 +00:00
|
|
|
static enum xrt_swapchain_create_flags
|
|
|
|
convert_create_flags(XrSwapchainCreateFlags xr_flags)
|
|
|
|
{
|
|
|
|
enum xrt_swapchain_create_flags flags = 0;
|
|
|
|
if ((xr_flags & XR_SWAPCHAIN_CREATE_STATIC_IMAGE_BIT) != 0) {
|
|
|
|
flags |= XRT_SWAPCHAIN_CREATE_STATIC_IMAGE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return flags;
|
|
|
|
}
|
|
|
|
|
2020-05-28 11:31:55 +00:00
|
|
|
static enum xrt_swapchain_usage_bits
|
|
|
|
convert_usage_bits(XrSwapchainUsageFlags xr_usage)
|
|
|
|
{
|
|
|
|
enum xrt_swapchain_usage_bits usage = 0;
|
|
|
|
|
|
|
|
if ((xr_usage & XR_SWAPCHAIN_USAGE_COLOR_ATTACHMENT_BIT) != 0) {
|
|
|
|
usage |= XRT_SWAPCHAIN_USAGE_COLOR;
|
|
|
|
}
|
|
|
|
if ((xr_usage & XR_SWAPCHAIN_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0) {
|
|
|
|
usage |= XRT_SWAPCHAIN_USAGE_DEPTH_STENCIL;
|
|
|
|
}
|
|
|
|
if ((xr_usage & XR_SWAPCHAIN_USAGE_UNORDERED_ACCESS_BIT) != 0) {
|
|
|
|
usage |= XRT_SWAPCHAIN_USAGE_UNORDERED_ACCESS;
|
|
|
|
}
|
|
|
|
if ((xr_usage & XR_SWAPCHAIN_USAGE_TRANSFER_SRC_BIT) != 0) {
|
|
|
|
usage |= XRT_SWAPCHAIN_USAGE_TRANSFER_SRC;
|
|
|
|
}
|
|
|
|
if ((xr_usage & XR_SWAPCHAIN_USAGE_TRANSFER_DST_BIT) != 0) {
|
|
|
|
usage |= XRT_SWAPCHAIN_USAGE_TRANSFER_DST;
|
|
|
|
}
|
|
|
|
if ((xr_usage & XR_SWAPCHAIN_USAGE_SAMPLED_BIT) != 0) {
|
|
|
|
usage |= XRT_SWAPCHAIN_USAGE_SAMPLED;
|
|
|
|
}
|
|
|
|
if ((xr_usage & XR_SWAPCHAIN_USAGE_MUTABLE_FORMAT_BIT) != 0) {
|
|
|
|
usage |= XRT_SWAPCHAIN_USAGE_MUTABLE_FORMAT;
|
|
|
|
}
|
|
|
|
|
|
|
|
return usage;
|
|
|
|
}
|
|
|
|
|
2019-03-18 05:52:32 +00:00
|
|
|
XrResult
|
|
|
|
oxr_create_swapchain(struct oxr_logger *log,
|
|
|
|
struct oxr_session *sess,
|
|
|
|
const XrSwapchainCreateInfo *createInfo,
|
|
|
|
struct oxr_swapchain **out_swapchain)
|
|
|
|
{
|
2019-10-28 21:00:36 +00:00
|
|
|
struct xrt_swapchain *xsc = xrt_comp_create_swapchain(
|
2020-05-27 18:53:22 +00:00
|
|
|
sess->compositor, convert_create_flags(createInfo->createFlags),
|
2020-05-28 11:31:55 +00:00
|
|
|
convert_usage_bits(createInfo->usageFlags), createInfo->format,
|
|
|
|
createInfo->sampleCount, createInfo->width, createInfo->height,
|
|
|
|
createInfo->faceCount, createInfo->arraySize, createInfo->mipCount);
|
2019-03-18 05:52:32 +00:00
|
|
|
|
|
|
|
if (xsc == NULL) {
|
|
|
|
return oxr_error(log, XR_ERROR_RUNTIME_FAILURE,
|
|
|
|
" failed to create swapchain");
|
|
|
|
}
|
|
|
|
|
2019-04-05 19:18:03 +00:00
|
|
|
struct oxr_swapchain *sc = NULL;
|
|
|
|
OXR_ALLOCATE_HANDLE_OR_RETURN(log, sc, OXR_XR_DEBUG_SWAPCHAIN,
|
|
|
|
oxr_swapchain_destroy, &sess->handle);
|
2019-03-18 05:52:32 +00:00
|
|
|
sc->sess = sess;
|
|
|
|
sc->swapchain = xsc;
|
|
|
|
sc->acquire_image = oxr_swapchain_acquire_image;
|
|
|
|
sc->wait_image = oxr_swapchain_wait_image;
|
|
|
|
sc->release_image = oxr_swapchain_release_image;
|
|
|
|
|
|
|
|
*out_swapchain = sc;
|
|
|
|
|
|
|
|
return XR_SUCCESS;
|
|
|
|
}
|