The open source OpenXR runtime
at main 135 lines 4.3 kB view raw
1// Copyright 2019-2022, Collabora, Ltd. 2// SPDX-License-Identifier: BSL-1.0 3/*! 4 * @file 5 * @brief D3D12 client side glue to compositor implementation. 6 * @author Rylie Pavlik <rylie.pavlik@collabora.com> 7 * @author Jakob Bornecrantz <jakob@collabora.com> 8 * @ingroup comp_client 9 */ 10 11#include "comp_d3d_common.hpp" 12 13#include "util/u_logging.h" 14#include "util/u_time.h" 15 16 17 18#define D3D_COMMON_SPEW(log_level, ...) U_LOG_IFL_T(log_level, __VA_ARGS__); 19 20#define D3D_COMMON_DEBUG(log_level, ...) U_LOG_IFL_D(log_level, __VA_ARGS__); 21 22#define D3D_COMMON_INFO(log_level, ...) U_LOG_IFL_I(log_level, __VA_ARGS__); 23 24#define D3D_COMMON_WARN(log_level, ...) U_LOG_IFL_W(log_level, __VA_ARGS__); 25 26#define D3D_COMMON_ERROR(log_level, ...) U_LOG_IFL_E(log_level, __VA_ARGS__); 27 28namespace xrt::compositor::client { 29 30static inline DWORD 31convertTimeoutToWindowsMilliseconds(uint64_t timeout_ns) 32{ 33 return (timeout_ns == XRT_INFINITE_DURATION) ? INFINITE : (DWORD)(timeout_ns / (uint64_t)U_TIME_1MS_IN_NS); 34} 35 36KeyedMutexCollection::KeyedMutexCollection(u_logging_level log_level) noexcept : log_level(log_level) {} 37 38xrt_result_t 39KeyedMutexCollection::init(const std::vector<wil::com_ptr<ID3D11Texture2D1>> &images) noexcept 40try { 41 keyed_mutex_collection.clear(); 42 keyed_mutex_collection.reserve(images.size()); 43 for (const auto &image : images) { 44 keyed_mutex_collection.emplace_back(image.query<IDXGIKeyedMutex>()); 45 } 46 47 keyed_mutex_acquired.clear(); 48 keyed_mutex_acquired.resize(keyed_mutex_collection.size()); 49 return XRT_SUCCESS; 50} catch (wil::ResultException const &e) { 51 U_LOG_E("Error getting keyed mutex collection for swapchain: %s", e.what()); 52 return XRT_ERROR_D3D; 53} catch (std::exception const &e) { 54 U_LOG_E("Error getting keyed mutex collection for swapchain: %s", e.what()); 55 return XRT_ERROR_D3D; 56} catch (...) { 57 U_LOG_E("Error getting keyed mutex collection for swapchain"); 58 return XRT_ERROR_D3D; 59} 60 61xrt_result_t 62KeyedMutexCollection::waitKeyedMutex(uint32_t index, uint64_t timeout_ns) noexcept 63 64try { 65 66 if (keyed_mutex_acquired[index]) { 67 68 D3D_COMMON_WARN(log_level, 69 "Will not acquire the keyed mutex for image %" PRId32 " - it was already acquired!", 70 index); 71 return XRT_ERROR_NO_IMAGE_AVAILABLE; 72 } 73 74 auto hr = 75 keyed_mutex_collection[index]->AcquireSync(kKeyedMutexKey, convertTimeoutToWindowsMilliseconds(timeout_ns)); 76 if (hr == WAIT_ABANDONED) { 77 D3D_COMMON_ERROR(log_level, 78 "Could not acquire the keyed mutex for image %" PRId32 79 " due to it being in an inconsistent state", 80 index); 81 return XRT_ERROR_D3D; 82 } 83 if (hr == WAIT_TIMEOUT) { 84 return XRT_TIMEOUT; 85 } 86 if (FAILED(hr)) { 87 D3D_COMMON_ERROR(log_level, "Could not acquire the keyed mutex for image %" PRId32, index); 88 return XRT_ERROR_D3D; 89 } 90 keyed_mutex_acquired[index] = true; 91 return XRT_SUCCESS; 92} catch (wil::ResultException const &e) { 93 U_LOG_E("Error acquiring keyed mutex for image %" PRId32 ": %s", index, e.what()); 94 return XRT_ERROR_D3D; 95} catch (std::exception const &e) { 96 U_LOG_E("Error acquiring keyed mutex for image %" PRId32 ": %s", index, e.what()); 97 return XRT_ERROR_D3D; 98} catch (...) { 99 U_LOG_E("Error acquiring keyed mutex for image %" PRId32, index); 100 return XRT_ERROR_D3D; 101} 102 103 104xrt_result_t 105KeyedMutexCollection::releaseKeyedMutex(uint32_t index) noexcept 106 107try { 108 109 if (!keyed_mutex_acquired[index]) { 110 111 D3D_COMMON_WARN(log_level, 112 "Will not release the keyed mutex for image %" PRId32 " - it was not acquired!", index); 113 return XRT_ERROR_D3D; 114 } 115 auto hr = LOG_IF_FAILED(keyed_mutex_collection[index]->ReleaseSync(kKeyedMutexKey)); 116 if (FAILED(hr)) { 117 D3D_COMMON_ERROR(log_level, "Could not release the keyed mutex for image %" PRId32, index); 118 return XRT_ERROR_D3D; 119 } 120 keyed_mutex_acquired[index] = false; 121 return XRT_SUCCESS; 122 123} catch (wil::ResultException const &e) { 124 U_LOG_E("Error releasing keyed mutex %" PRId32 ": %s", index, e.what()); 125 return XRT_ERROR_D3D; 126} catch (std::exception const &e) { 127 U_LOG_E("Error releasing keyed mutex %" PRId32 ": %s", index, e.what()); 128 return XRT_ERROR_D3D; 129} catch (...) { 130 U_LOG_E("Error releasing keyed mutex %" PRId32, index); 131 return XRT_ERROR_D3D; 132} 133 134 135} // namespace xrt::compositor::client