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