Monado OpenXR Runtime
comp_d3d_common.hpp
Go to the documentation of this file.
1// Copyright 2019-2024, Collabora, Ltd.
2// SPDX-License-Identifier: BSL-1.0
3/*!
4 * @file
5 * @brief Functionality common to D3D11 and D3D12 for client side compositor implementation.
6 * @author Rylie Pavlik <rylie.pavlik@collabora.com>
7 * @author Jakob Bornecrantz <jakob@collabora.com>
8 * @author Fernando Velazquez Innella <finnella@magicleap.com>
9 * @author Korcan Hussein <korcan.hussein@collabora.com>
10 * @ingroup comp_client
11 */
12#pragma once
13
14#include "xrt/xrt_compositor.h"
15#include "xrt/xrt_deleters.hpp"
16#include "xrt/xrt_results.h"
17
18#include "util/u_handles.h"
19#include "util/u_logging.h"
20
21#include <wil/com.h>
22#include <wil/resource.h>
23#include <wil/result_macros.h>
24
25#include <d3d11_3.h>
26
27#include <memory>
28#include <vector>
29#include <stdint.h>
30
31
32namespace xrt::compositor::client {
33
34using unique_swapchain_ref =
35 std::unique_ptr<struct xrt_swapchain,
36 xrt::deleters::reference_deleter<struct xrt_swapchain, xrt_swapchain_reference>>;
37
38
39/**
40 * Import the provided handles into a native compositor, without consuming them.
41 *
42 * @param xcn The native compositor
43 * @param handles A vector of uniquely-owned handles. These will be duplicated, not consumed, by this import.
44 * @param vkinfo The swapchain create info, with format as a Vulkan constant
45 * @param image_mem_size The image memory allocation size in bytes
46 * @param use_dedicated_allocation Passed through to @ref xrt_image_native
47 * @param[out] out_xsc The swapchain to populate
48 * @return XRT_SUCCESS if everything went well, otherwise whatever error a call internally returned.
49 */
50static inline xrt_result_t
51importFromHandleDuplicates(xrt_compositor_native &xcn,
52 std::vector<wil::unique_handle> const &handles,
53 const struct xrt_swapchain_create_info &vkinfo,
54 const std::uint64_t image_mem_size,
55 bool use_dedicated_allocation,
56 unique_swapchain_ref &out_xsc)
57{
58 uint32_t image_count = static_cast<uint32_t>(handles.size());
59 // Populate for import
60 std::vector<xrt_image_native> xins;
61 xins.reserve(image_count);
62
63 // Keep this around until after successful import, then detach all.
64 std::vector<wil::unique_handle> handlesForImport;
65 handlesForImport.reserve(image_count);
66
67 for (const wil::unique_handle &handle : handles) {
68 wil::unique_handle duped{u_graphics_buffer_ref(handle.get())};
69 xrt_image_native xin{};
70 xin.handle = duped.get();
71 xin.size = image_mem_size;
72 xin.use_dedicated_allocation = use_dedicated_allocation;
73
74 handlesForImport.emplace_back(std::move(duped));
75 xins.emplace_back(xin);
76 }
77
78 // Import into the native compositor, to create the corresponding swapchain which we wrap.
79 xrt_swapchain *xsc = nullptr;
80 xrt_result_t xret = xrt_comp_import_swapchain(&(xcn.base), &vkinfo, xins.data(), image_count, &xsc);
81 if (xret != XRT_SUCCESS) {
82 return xret;
83 }
84 // Let unique_ptr manage the lifetime of xsc now
85 out_xsc.reset(xsc);
86
87 // The imported swapchain took ownership of them now, release them from ownership here.
88 for (auto &h : handlesForImport) {
89 h.release();
90 }
91 return XRT_SUCCESS;
92}
93
94
95/**
96 * Import the provided handles into a native compositor.
97 *
98 * @param xcn The native compositor
99 * @param handles A vector of DXGI handles.
100 * @param vkinfo The swapchain create info, with format as a Vulkan constant
101 * @param use_dedicated_allocation Passed through to @ref xrt_image_native
102 * @param[out] out_xsc The swapchain to populate
103 * @return XRT_SUCCESS if everything went well, otherwise whatever error a call internally returned.
104 */
105static inline xrt_result_t
107 std::vector<HANDLE> const &handles,
108 const struct xrt_swapchain_create_info &vkinfo,
109 bool use_dedicated_allocation,
110 unique_swapchain_ref &out_xsc)
111{
112 uint32_t image_count = static_cast<uint32_t>(handles.size());
113 // Populate for import
114 std::vector<xrt_image_native> xins;
115 xins.reserve(image_count);
116
117 for (HANDLE handle : handles) {
118 xrt_image_native xin{};
119 xin.handle = handle;
120 xin.size = 0;
121 xin.use_dedicated_allocation = use_dedicated_allocation;
122 xin.is_dxgi_handle = true;
123
124 xins.emplace_back(xin);
125 }
126
127 // Import into the native compositor, to create the corresponding swapchain which we wrap.
128 xrt_swapchain *xsc = nullptr;
129 xrt_result_t xret = xrt_comp_import_swapchain(&(xcn.base), &vkinfo, xins.data(), image_count, &xsc);
130 if (xret != XRT_SUCCESS) {
131 return xret;
132 }
133 // Let unique_ptr manage the lifetime of xsc now
134 out_xsc.reset(xsc);
135
136 return XRT_SUCCESS;
137}
138
139/**
140 * A collection of DXGIKeyedMutex objects, one for each swapchain image in a swapchain.
141 *
142 */
144{
145public:
146 // 0 is special
147 static constexpr uint64_t kKeyedMutexKey = 0;
148
149 /**
150 * @brief Construct a new Keyed Mutex Collection object
151 *
152 * @param log_level The compositor log level to use
153 */
154 explicit KeyedMutexCollection(u_logging_level log_level) noexcept;
155
156 /**
157 * Make the keyed mutex vector before starting to use the images.
158 *
159 * @param images Your vector of textures to acquire keyed mutexes from.
160 */
162 init(const std::vector<wil::com_ptr<ID3D11Texture2D1>> &images) noexcept;
163
164 /**
165 * Wait for acquisition of the keyed mutex.
166 *
167 * @param index Swapchain image index
168 * @param timeout_ns Timeout in nanoseconds or XRT_INFINITE_DURATION
169 * @return xrt_result_t: XRT_SUCCESS, XRT_TIMEOUT, or some error
170 */
172 waitKeyedMutex(uint32_t index, uint64_t timeout_ns) noexcept;
173
174 /**
175 * Release the keyed mutex
176 *
177 * @param index Swapchain image index
178 * @return xrt_result_t
179 */
181 releaseKeyedMutex(uint32_t index) noexcept;
182
183private:
184 //! Keyed mutex per image associated with client_d3d11_compositor::app_device
185 std::vector<wil::com_ptr<IDXGIKeyedMutex>> keyed_mutex_collection;
186
187 std::vector<bool> keyed_mutex_acquired;
188
189 //! Logging level.
190 u_logging_level log_level;
191};
192
193
194} // namespace xrt::compositor::client
A collection of DXGIKeyedMutex objects, one for each swapchain image in a swapchain.
Definition: comp_d3d_common.hpp:144
xrt_result_t init(const std::vector< wil::com_ptr< ID3D11Texture2D1 > > &images) noexcept
Make the keyed mutex vector before starting to use the images.
Definition: comp_d3d_common.cpp:39
xrt_result_t releaseKeyedMutex(uint32_t index) noexcept
Release the keyed mutex.
Definition: comp_d3d_common.cpp:105
KeyedMutexCollection(u_logging_level log_level) noexcept
Construct a new Keyed Mutex Collection object.
Definition: comp_d3d_common.cpp:36
xrt_result_t waitKeyedMutex(uint32_t index, uint64_t timeout_ns) noexcept
Wait for acquisition of the keyed mutex.
Definition: comp_d3d_common.cpp:62
static xrt_result_t importFromHandleDuplicates(xrt_compositor_native &xcn, std::vector< wil::unique_handle > const &handles, const struct xrt_swapchain_create_info &vkinfo, const std::uint64_t image_mem_size, bool use_dedicated_allocation, unique_swapchain_ref &out_xsc)
Import the provided handles into a native compositor, without consuming them.
Definition: comp_d3d_common.hpp:51
static xrt_result_t importFromDxgiHandles(xrt_compositor_native &xcn, std::vector< HANDLE > const &handles, const struct xrt_swapchain_create_info &vkinfo, bool use_dedicated_allocation, unique_swapchain_ref &out_xsc)
Import the provided handles into a native compositor.
Definition: comp_d3d_common.hpp:106
u_logging_level
Logging level enum.
Definition: u_logging.h:43
enum xrt_result xrt_result_t
Result type used across Monado.
@ XRT_SUCCESS
The operation succeeded.
Definition: xrt_results.h:26
Main compositor server interface.
Definition: xrt_compositor.h:2224
struct xrt_compositor base
Base.
Definition: xrt_compositor.h:2226
A single image of a swapchain based on native buffer handles.
Definition: xrt_compositor.h:2150
xrt_graphics_buffer_handle_t handle
Native buffer handle.
Definition: xrt_compositor.h:2154
Swapchain creation info.
Definition: xrt_compositor.h:876
Common swapchain interface/base.
Definition: xrt_compositor.h:536
Functions for dealing generically with various handle types defined in xrt_handles....
Basic logging functionality.
Header declaring XRT graphics interfaces.
Generic unique_ptr deleters for Monado types.
Internal result type for XRT.