mirror of
https://gitlab.freedesktop.org/monado/monado.git
synced 2025-01-28 17:38:27 +00:00
c/client: Extract some utilities usable by D3D11 and 12
This commit is contained in:
parent
576b158a83
commit
a9facfe671
|
@ -5,6 +5,7 @@
|
|||
- mr.1326
|
||||
- mr.1302
|
||||
- mr.1337
|
||||
- mr.1340
|
||||
---
|
||||
|
||||
Full support for D3D11 client applications on Windows.
|
||||
|
|
|
@ -58,6 +58,14 @@ if(XRT_HAVE_EGL)
|
|||
target_sources(comp_client PRIVATE client/comp_egl_client.c client/comp_egl_client.h)
|
||||
endif()
|
||||
|
||||
if(XRT_HAVE_D3D11 OR XRT_HAVE_D3D12)
|
||||
target_link_libraries(comp_client PRIVATE aux_d3d)
|
||||
endif()
|
||||
|
||||
if(XRT_HAVE_D3D11 OR XRT_HAVE_D3D12)
|
||||
target_sources(comp_client PRIVATE client/comp_d3d_common.cpp client/comp_d3d_common.hpp)
|
||||
endif()
|
||||
|
||||
if(XRT_HAVE_D3D11)
|
||||
target_sources(
|
||||
comp_client PRIVATE client/comp_d3d11_client.cpp client/comp_d3d11_client.h
|
||||
|
@ -65,6 +73,7 @@ if(XRT_HAVE_D3D11)
|
|||
)
|
||||
target_link_libraries(comp_client PRIVATE aux_d3d)
|
||||
endif()
|
||||
|
||||
##
|
||||
# Util library
|
||||
#
|
||||
|
@ -259,7 +268,6 @@ if(XRT_FEATURE_COMPOSITOR_MAIN)
|
|||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
###
|
||||
# Null compositor
|
||||
#
|
||||
|
@ -268,7 +276,6 @@ if(XRT_FEATURE_COMPOSITOR_NULL)
|
|||
add_subdirectory(null)
|
||||
endif()
|
||||
|
||||
|
||||
###
|
||||
# Multi client compositor library
|
||||
#
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
|
||||
#include "comp_d3d11_client.h"
|
||||
|
||||
#include "comp_d3d_common.hpp"
|
||||
|
||||
#include "xrt/xrt_compositor.h"
|
||||
#include "xrt/xrt_config_os.h"
|
||||
#include "xrt/xrt_handles.h"
|
||||
|
@ -45,6 +47,8 @@
|
|||
using namespace std::chrono_literals;
|
||||
using namespace std::chrono;
|
||||
|
||||
using xrt::compositor::client::unique_swapchain_ref;
|
||||
|
||||
DEBUG_GET_ONCE_LOG_OPTION(log, "D3D_COMPOSITOR_LOG", U_LOGGING_INFO)
|
||||
|
||||
/*!
|
||||
|
@ -86,10 +90,6 @@ using unique_compositor_semaphore_ref = std::unique_ptr<
|
|||
struct xrt_compositor_semaphore,
|
||||
xrt::deleters::reference_deleter<struct xrt_compositor_semaphore, xrt_compositor_semaphore_reference>>;
|
||||
|
||||
using unique_swapchain_ref =
|
||||
std::unique_ptr<struct xrt_swapchain,
|
||||
xrt::deleters::reference_deleter<struct xrt_swapchain, xrt_swapchain_reference>>;
|
||||
|
||||
// 0 is special
|
||||
static constexpr uint64_t kKeyedMutexKey = 0;
|
||||
|
||||
|
@ -182,6 +182,10 @@ convertTimeoutToWindowsMilliseconds(uint64_t timeout_ns)
|
|||
*/
|
||||
struct client_d3d11_swapchain_data
|
||||
{
|
||||
explicit client_d3d11_swapchain_data(enum u_logging_level log_level) : keyed_mutex_collection(log_level) {}
|
||||
|
||||
xrt::compositor::client::KeyedMutexCollection keyed_mutex_collection;
|
||||
|
||||
//! The shared handles for all our images
|
||||
std::vector<wil::unique_handle> handles;
|
||||
|
||||
|
@ -190,16 +194,6 @@ struct client_d3d11_swapchain_data
|
|||
|
||||
//! Images associated with client_d3d11_compositor::comp_device
|
||||
std::vector<wil::com_ptr<ID3D11Texture2D1>> comp_images;
|
||||
|
||||
//! Keyed mutex per image associated with client_d3d11_compositor::app_device
|
||||
std::vector<wil::com_ptr<IDXGIKeyedMutex>> app_keyed_mutex_collection;
|
||||
|
||||
std::vector<bool> keyed_mutex_acquired;
|
||||
|
||||
xrt_result_t
|
||||
waitImage(client_d3d11_swapchain *sc, uint32_t index, uint64_t timeout_ns);
|
||||
xrt_result_t
|
||||
releaseImage(client_d3d11_swapchain *sc, uint32_t index);
|
||||
};
|
||||
|
||||
/*!
|
||||
|
@ -265,63 +259,6 @@ formatMessage(DWORD err, char (&buf)[N])
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* Helpers for Swapchain
|
||||
*
|
||||
*/
|
||||
|
||||
inline xrt_result_t
|
||||
client_d3d11_swapchain_data::waitImage(client_d3d11_swapchain *sc, uint32_t index, uint64_t timeout_ns)
|
||||
{
|
||||
if (keyed_mutex_acquired[index]) {
|
||||
|
||||
D3D_WARN(sc->c, "Will not acquire the keyed mutex for image %" PRId32 " - it was already acquired!",
|
||||
index);
|
||||
return XRT_ERROR_NO_IMAGE_AVAILABLE;
|
||||
}
|
||||
|
||||
auto hr = app_keyed_mutex_collection[index]->AcquireSync(kKeyedMutexKey,
|
||||
convertTimeoutToWindowsMilliseconds(timeout_ns));
|
||||
if (hr == WAIT_ABANDONED) {
|
||||
D3D_ERROR(sc->c,
|
||||
"Could not acquire the keyed mutex for image %" PRId32
|
||||
" due to it being in an inconsistent state",
|
||||
index);
|
||||
return XRT_ERROR_D3D11;
|
||||
}
|
||||
if (hr == WAIT_TIMEOUT) {
|
||||
return XRT_TIMEOUT;
|
||||
}
|
||||
if (FAILED(hr)) {
|
||||
D3D_ERROR(sc->c, "Could not acquire the keyed mutex for image %" PRId32, index);
|
||||
return XRT_ERROR_D3D11;
|
||||
}
|
||||
keyed_mutex_acquired[index] = true;
|
||||
sc->c->app_context->Flush();
|
||||
//! @todo this causes an error in the debug layer
|
||||
// Discard old contents
|
||||
// sc->c->app_context->DiscardResource(wil::com_raw_ptr(app_images[index]));
|
||||
return XRT_SUCCESS;
|
||||
}
|
||||
|
||||
inline xrt_result_t
|
||||
client_d3d11_swapchain_data::releaseImage(client_d3d11_swapchain *sc, uint32_t index)
|
||||
{
|
||||
if (!keyed_mutex_acquired[index]) {
|
||||
|
||||
D3D_WARN(sc->c, "Will not release the keyed mutex for image %" PRId32 " - it was not acquired!", index);
|
||||
return XRT_ERROR_D3D11;
|
||||
}
|
||||
auto hr = LOG_IF_FAILED(app_keyed_mutex_collection[index]->ReleaseSync(kKeyedMutexKey));
|
||||
if (FAILED(hr)) {
|
||||
D3D_ERROR(sc->c, "Could not release the keyed mutex for image %" PRId32, index);
|
||||
return XRT_ERROR_D3D11;
|
||||
}
|
||||
sc->data->keyed_mutex_acquired[index] = false;
|
||||
return XRT_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* Swapchain functions.
|
||||
|
@ -347,8 +284,10 @@ client_d3d11_swapchain_wait_image(struct xrt_swapchain *xsc, uint64_t timeout_ns
|
|||
|
||||
if (xret == XRT_SUCCESS) {
|
||||
// OK, we got the image in the native compositor, now need the keyed mutex in d3d11.
|
||||
return sc->data->waitImage(sc, index, timeout_ns);
|
||||
xret = sc->data->keyed_mutex_collection.waitKeyedMutex(index, timeout_ns);
|
||||
}
|
||||
|
||||
//! @todo discard old contents?
|
||||
return xret;
|
||||
}
|
||||
|
||||
|
@ -361,7 +300,8 @@ client_d3d11_swapchain_release_image(struct xrt_swapchain *xsc, uint32_t index)
|
|||
xrt_result_t xret = xrt_swapchain_release_image(sc->xsc.get(), index);
|
||||
|
||||
if (xret == XRT_SUCCESS) {
|
||||
return sc->data->releaseImage(sc, index);
|
||||
// Release the keyed mutex
|
||||
xret = sc->data->keyed_mutex_collection.releaseKeyedMutex(index);
|
||||
}
|
||||
return xret;
|
||||
}
|
||||
|
@ -439,15 +379,13 @@ try {
|
|||
vkinfo.format = vk_format;
|
||||
|
||||
std::unique_ptr<struct client_d3d11_swapchain> sc = std::make_unique<struct client_d3d11_swapchain>();
|
||||
sc->data = std::make_unique<client_d3d11_swapchain_data>();
|
||||
sc->data = std::make_unique<client_d3d11_swapchain_data>(c->log_level);
|
||||
auto &data = sc->data;
|
||||
xret = xrt::auxiliary::d3d::d3d11::allocateSharedImages(*(c->comp_device), xinfo, image_count, true,
|
||||
data->comp_images, data->handles);
|
||||
if (xret != XRT_SUCCESS) {
|
||||
return xret;
|
||||
}
|
||||
data->keyed_mutex_acquired.resize(image_count);
|
||||
sc->data->app_keyed_mutex_collection.reserve(image_count);
|
||||
data->app_images.reserve(image_count);
|
||||
|
||||
// Import from the handle for the app.
|
||||
|
@ -458,45 +396,24 @@ try {
|
|||
// Put the image where the OpenXR state tracker can get it
|
||||
sc->base.images[i] = image.get();
|
||||
|
||||
// Cache the keyed mutex interface too
|
||||
sc->data->app_keyed_mutex_collection.emplace_back(image.query<IDXGIKeyedMutex>());
|
||||
|
||||
// Store the owning pointer for lifetime management
|
||||
data->app_images.emplace_back(std::move(image));
|
||||
}
|
||||
|
||||
// Populate for import
|
||||
std::vector<xrt_image_native> xins;
|
||||
xins.reserve(data->handles.size());
|
||||
// Keep this around until after successful import, then detach all.
|
||||
std::vector<wil::unique_handle> handlesForImport;
|
||||
handlesForImport.reserve(data->handles.size());
|
||||
|
||||
for (const wil::unique_handle &handle : data->handles) {
|
||||
wil::unique_handle duped{u_graphics_buffer_ref(handle.get())};
|
||||
xrt_image_native xin;
|
||||
xin.handle = duped.get();
|
||||
xin.size = 0;
|
||||
xin.use_dedicated_allocation = false; //! @todo not sure
|
||||
|
||||
handlesForImport.emplace_back(std::move(duped));
|
||||
xins.emplace_back(xin);
|
||||
// Cache the keyed mutex interface
|
||||
xret = data->keyed_mutex_collection.init(data->app_images);
|
||||
if (xret != XRT_SUCCESS) {
|
||||
D3D_ERROR(c, "Error retrieving keyex mutex interfaces");
|
||||
return xret;
|
||||
}
|
||||
|
||||
// Import into the native compositor, to create the corresponding swapchain which we wrap.
|
||||
xrt_swapchain *xsc = nullptr;
|
||||
xret = xrt_comp_import_swapchain(&(c->xcn->base), &vkinfo, xins.data(), image_count, &xsc);
|
||||
xret = xrt::compositor::client::importFromHandleDuplicates(
|
||||
*(c->xcn), data->handles, vkinfo, false /** @todo not sure - dedicated allocation */, sc->xsc);
|
||||
if (xret != XRT_SUCCESS) {
|
||||
D3D_ERROR(c, "Error importing D3D11 swapchain into native compositor");
|
||||
return xret;
|
||||
}
|
||||
// The imported swapchain took ownership of them now, release them from ownership here.
|
||||
for (auto &h : handlesForImport) {
|
||||
h.release();
|
||||
}
|
||||
|
||||
// Let unique_ptr manage the lifetime of xsc now
|
||||
sc->xsc.reset(xsc);
|
||||
|
||||
sc->base.base.destroy = client_d3d11_swapchain_destroy;
|
||||
sc->base.base.acquire_image = client_d3d11_swapchain_acquire_image;
|
||||
|
|
144
src/xrt/compositor/client/comp_d3d_common.cpp
Normal file
144
src/xrt/compositor/client/comp_d3d_common.cpp
Normal file
|
@ -0,0 +1,144 @@
|
|||
// Copyright 2019-2022, Collabora, Ltd.
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
/*!
|
||||
* @file
|
||||
* @brief D3D12 client side glue to compositor implementation.
|
||||
* @author Ryan Pavlik <ryan.pavlik@collabora.com>
|
||||
* @author Jakob Bornecrantz <jakob@collabora.com>
|
||||
* @ingroup comp_client
|
||||
*/
|
||||
|
||||
#include "comp_d3d_common.hpp"
|
||||
|
||||
#include "util/u_logging.h"
|
||||
#include "util/u_time.h"
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
|
||||
#define D3D_COMMON_SPEW(log_level, ...) U_LOG_IFL_T(log_level, __VA_ARGS__);
|
||||
|
||||
#define D3D_COMMON_DEBUG(log_level, ...) U_LOG_IFL_D(log_level, __VA_ARGS__);
|
||||
|
||||
#define D3D_COMMON_INFO(log_level, ...) U_LOG_IFL_I(log_level, __VA_ARGS__);
|
||||
|
||||
#define D3D_COMMON_WARN(log_level, ...) U_LOG_IFL_W(log_level, __VA_ARGS__);
|
||||
|
||||
#define D3D_COMMON_ERROR(log_level, ...) U_LOG_IFL_E(log_level, __VA_ARGS__);
|
||||
|
||||
namespace xrt::compositor::client {
|
||||
|
||||
// xrt_result_t
|
||||
// importFromHandleDuplicates(xrt_compositor_native &xcn,
|
||||
// std::vector<wil::unique_handle> const &handles,
|
||||
// const xrt_swapchain_create_info &vkinfo,
|
||||
// bool use_dedicated_allocation,
|
||||
// unique_swapchain_ref &out_xsc)
|
||||
|
||||
|
||||
static inline DWORD
|
||||
convertTimeoutToWindowsMilliseconds(uint64_t timeout_ns)
|
||||
{
|
||||
return (timeout_ns == XRT_INFINITE_DURATION) ? INFINITE : (DWORD)(timeout_ns / (uint64_t)U_TIME_1MS_IN_NS);
|
||||
}
|
||||
|
||||
KeyedMutexCollection::KeyedMutexCollection(u_logging_level log_level) noexcept : log_level(log_level) {}
|
||||
|
||||
xrt_result_t
|
||||
KeyedMutexCollection::init(const std::vector<wil::com_ptr<ID3D11Texture2D1>> &images) noexcept
|
||||
try {
|
||||
keyed_mutex_collection.clear();
|
||||
keyed_mutex_collection.reserve(images.size());
|
||||
for (const auto &image : images) {
|
||||
keyed_mutex_collection.emplace_back(image.query<IDXGIKeyedMutex>());
|
||||
}
|
||||
|
||||
keyed_mutex_acquired.clear();
|
||||
keyed_mutex_acquired.resize(keyed_mutex_collection.size());
|
||||
return XRT_SUCCESS;
|
||||
} catch (wil::ResultException const &e) {
|
||||
U_LOG_E("Error getting keyed mutex collection for swapchain: %s", e.what());
|
||||
return XRT_ERROR_D3D;
|
||||
} catch (std::exception const &e) {
|
||||
U_LOG_E("Error getting keyed mutex collection for swapchain: %s", e.what());
|
||||
return XRT_ERROR_D3D;
|
||||
} catch (...) {
|
||||
U_LOG_E("Error getting keyed mutex collection for swapchain");
|
||||
return XRT_ERROR_D3D;
|
||||
}
|
||||
|
||||
xrt_result_t
|
||||
KeyedMutexCollection::waitKeyedMutex(uint32_t index, uint64_t timeout_ns) noexcept
|
||||
|
||||
try {
|
||||
|
||||
if (keyed_mutex_acquired[index]) {
|
||||
|
||||
D3D_COMMON_WARN(log_level,
|
||||
"Will not acquire the keyed mutex for image %" PRId32 " - it was already acquired!",
|
||||
index);
|
||||
return XRT_ERROR_NO_IMAGE_AVAILABLE;
|
||||
}
|
||||
|
||||
auto hr =
|
||||
keyed_mutex_collection[index]->AcquireSync(kKeyedMutexKey, convertTimeoutToWindowsMilliseconds(timeout_ns));
|
||||
if (hr == WAIT_ABANDONED) {
|
||||
D3D_COMMON_ERROR(log_level,
|
||||
"Could not acquire the keyed mutex for image %" PRId32
|
||||
" due to it being in an inconsistent state",
|
||||
index);
|
||||
return XRT_ERROR_D3D;
|
||||
}
|
||||
if (hr == WAIT_TIMEOUT) {
|
||||
return XRT_TIMEOUT;
|
||||
}
|
||||
if (FAILED(hr)) {
|
||||
D3D_COMMON_ERROR(log_level, "Could not acquire the keyed mutex for image %" PRId32, index);
|
||||
return XRT_ERROR_D3D;
|
||||
}
|
||||
keyed_mutex_acquired[index] = true;
|
||||
return XRT_SUCCESS;
|
||||
} catch (wil::ResultException const &e) {
|
||||
U_LOG_E("Error acquiring keyed mutex for image %" PRId32 ": %s", index, e.what());
|
||||
return XRT_ERROR_D3D;
|
||||
} catch (std::exception const &e) {
|
||||
U_LOG_E("Error acquiring keyed mutex for image %" PRId32 ": %s", index, e.what());
|
||||
return XRT_ERROR_D3D;
|
||||
} catch (...) {
|
||||
U_LOG_E("Error acquiring keyed mutex for image %" PRId32, index);
|
||||
return XRT_ERROR_D3D;
|
||||
}
|
||||
|
||||
|
||||
xrt_result_t
|
||||
KeyedMutexCollection::releaseKeyedMutex(uint32_t index) noexcept
|
||||
|
||||
try {
|
||||
|
||||
if (!keyed_mutex_acquired[index]) {
|
||||
|
||||
D3D_COMMON_WARN(log_level,
|
||||
"Will not release the keyed mutex for image %" PRId32 " - it was not acquired!", index);
|
||||
return XRT_ERROR_D3D;
|
||||
}
|
||||
auto hr = LOG_IF_FAILED(keyed_mutex_collection[index]->ReleaseSync(kKeyedMutexKey));
|
||||
if (FAILED(hr)) {
|
||||
D3D_COMMON_ERROR(log_level, "Could not release the keyed mutex for image %" PRId32, index);
|
||||
return XRT_ERROR_D3D;
|
||||
}
|
||||
keyed_mutex_acquired[index] = false;
|
||||
return XRT_SUCCESS;
|
||||
|
||||
} catch (wil::ResultException const &e) {
|
||||
U_LOG_E("Error releasing keyed mutex %" PRId32 ": %s", index, e.what());
|
||||
return XRT_ERROR_D3D;
|
||||
} catch (std::exception const &e) {
|
||||
U_LOG_E("Error releasing keyed mutex %" PRId32 ": %s", index, e.what());
|
||||
return XRT_ERROR_D3D;
|
||||
} catch (...) {
|
||||
U_LOG_E("Error releasing keyed mutex %" PRId32, index);
|
||||
return XRT_ERROR_D3D;
|
||||
}
|
||||
|
||||
|
||||
} // namespace xrt::compositor::client
|
144
src/xrt/compositor/client/comp_d3d_common.hpp
Normal file
144
src/xrt/compositor/client/comp_d3d_common.hpp
Normal file
|
@ -0,0 +1,144 @@
|
|||
// Copyright 2019-2022, Collabora, Ltd.
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
/*!
|
||||
* @file
|
||||
* @brief Functionality common to D3D11 and D3D12 for client side compositor implementation.
|
||||
* @author Ryan Pavlik <ryan.pavlik@collabora.com>
|
||||
* @author Jakob Bornecrantz <jakob@collabora.com>
|
||||
* @ingroup comp_client
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "xrt/xrt_compositor.h"
|
||||
#include "xrt/xrt_deleters.hpp"
|
||||
#include "xrt/xrt_results.h"
|
||||
|
||||
#include "util/u_handles.h"
|
||||
#include "util/u_logging.h"
|
||||
|
||||
#include <wil/com.h>
|
||||
#include <wil/resource.h>
|
||||
#include <wil/result_macros.h>
|
||||
|
||||
#include <d3d11_3.h>
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
namespace xrt::compositor::client {
|
||||
|
||||
using unique_swapchain_ref =
|
||||
std::unique_ptr<struct xrt_swapchain,
|
||||
xrt::deleters::reference_deleter<struct xrt_swapchain, xrt_swapchain_reference>>;
|
||||
|
||||
/**
|
||||
* Import the provided handles into a native compositor, without consuming them.
|
||||
*
|
||||
* @param c The native compositor
|
||||
* @param handles A vector of uniquely-owned handles. These will be duplicated, not consumed, by this import.
|
||||
* @param vkinfo The swapchain create info, with format as a Vulkan constant
|
||||
* @param use_dedicated_allocation Passed through to @ref xrt_image_native
|
||||
* @param[out] out_xsc The swapchain to populate
|
||||
* @return XRT_SUCCESS if everything went well, otherwise whatever error a call internally returned.
|
||||
*/
|
||||
static inline xrt_result_t
|
||||
importFromHandleDuplicates(xrt_compositor_native &xcn,
|
||||
std::vector<wil::unique_handle> const &handles,
|
||||
const struct xrt_swapchain_create_info &vkinfo,
|
||||
bool use_dedicated_allocation,
|
||||
unique_swapchain_ref &out_xsc)
|
||||
{
|
||||
uint32_t image_count = static_cast<uint32_t>(handles.size());
|
||||
// Populate for import
|
||||
std::vector<xrt_image_native> xins;
|
||||
xins.reserve(image_count);
|
||||
|
||||
// Keep this around until after successful import, then detach all.
|
||||
std::vector<wil::unique_handle> handlesForImport;
|
||||
handlesForImport.reserve(image_count);
|
||||
|
||||
for (const wil::unique_handle &handle : handles) {
|
||||
wil::unique_handle duped{u_graphics_buffer_ref(handle.get())};
|
||||
xrt_image_native xin;
|
||||
xin.handle = duped.get();
|
||||
xin.size = 0;
|
||||
xin.use_dedicated_allocation = use_dedicated_allocation;
|
||||
|
||||
handlesForImport.emplace_back(std::move(duped));
|
||||
xins.emplace_back(xin);
|
||||
}
|
||||
|
||||
// Import into the native compositor, to create the corresponding swapchain which we wrap.
|
||||
xrt_swapchain *xsc = nullptr;
|
||||
xrt_result_t xret = xrt_comp_import_swapchain(&(xcn.base), &vkinfo, xins.data(), image_count, &xsc);
|
||||
if (xret != XRT_SUCCESS) {
|
||||
return xret;
|
||||
}
|
||||
// Let unique_ptr manage the lifetime of xsc now
|
||||
out_xsc.reset(xsc);
|
||||
|
||||
// The imported swapchain took ownership of them now, release them from ownership here.
|
||||
for (auto &h : handlesForImport) {
|
||||
h.release();
|
||||
}
|
||||
return XRT_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* A collection of DXGIKeyedMutex objects, one for each swapchain image in a swapchain.
|
||||
*
|
||||
*/
|
||||
class KeyedMutexCollection
|
||||
{
|
||||
public:
|
||||
// 0 is special
|
||||
static constexpr uint64_t kKeyedMutexKey = 0;
|
||||
|
||||
/**
|
||||
* @brief Construct a new Keyed Mutex Collection object
|
||||
*
|
||||
* @param log_level The compositor log level to use
|
||||
*/
|
||||
explicit KeyedMutexCollection(u_logging_level log_level) noexcept;
|
||||
|
||||
/**
|
||||
* Take the keyed mutex vector before starting to use the images.
|
||||
*
|
||||
* @param keyedMutexVector Your vector of objects to move from
|
||||
*/
|
||||
xrt_result_t
|
||||
init(const std::vector<wil::com_ptr<ID3D11Texture2D1>> &images) noexcept;
|
||||
|
||||
/**
|
||||
* Wait for acquisition of the keyed mutex.
|
||||
*
|
||||
* @param index Swapchain image index
|
||||
* @param timeout_ns Timeout in nanoseconds or XRT_INFINITE_DURATION
|
||||
* @return xrt_result_t: XRT_SUCCESS, XRT_TIMEOUT, or some error
|
||||
*/
|
||||
xrt_result_t
|
||||
waitKeyedMutex(uint32_t index, uint64_t timeout_ns) noexcept;
|
||||
|
||||
/**
|
||||
* Release the keyed mutex
|
||||
*
|
||||
* @param index Swapchain image index
|
||||
* @return xrt_result_t
|
||||
*/
|
||||
xrt_result_t
|
||||
releaseKeyedMutex(uint32_t index) noexcept;
|
||||
|
||||
private:
|
||||
//! Keyed mutex per image associated with client_d3d11_compositor::app_device
|
||||
std::vector<wil::com_ptr<IDXGIKeyedMutex>> keyed_mutex_collection;
|
||||
|
||||
std::vector<bool> keyed_mutex_acquired;
|
||||
|
||||
//! Logging level.
|
||||
u_logging_level log_level;
|
||||
};
|
||||
|
||||
|
||||
} // namespace xrt::compositor::client
|
Loading…
Reference in a new issue