The open source OpenXR runtime
1// Copyright 2022, Collabora, Ltd.
2// SPDX-License-Identifier: BSL-1.0
3/*!
4 * @file
5 * @brief Misc D3D11 helper routines.
6 * @author Rylie Pavlik <rylie.pavlik@collabora.com>
7 * @ingroup aux_d3d
8 */
9
10#include "d3d_d3d11_helpers.hpp"
11
12#include "util/u_logging.h"
13
14#include <dxgi1_6.h>
15#include <d3d11_4.h>
16#include <wil/com.h>
17#include <wil/result.h>
18
19#include <vector>
20
21namespace xrt::auxiliary::d3d::d3d11 {
22HRESULT
23tryCreateDevice(const wil::com_ptr<IDXGIAdapter> &adapter,
24 D3D_DRIVER_TYPE driver_type,
25 unsigned int creation_flags,
26 const std::vector<D3D_FEATURE_LEVEL> &feature_levels,
27 wil::com_ptr<ID3D11Device> &out_device,
28 wil::com_ptr<ID3D11DeviceContext> &out_context)
29{
30 return D3D11CreateDevice(wil::com_raw_ptr(adapter), driver_type, nullptr, creation_flags, feature_levels.data(),
31 (UINT)feature_levels.size(), D3D11_SDK_VERSION, out_device.put(), nullptr,
32 out_context.put());
33}
34
35std::pair<wil::com_ptr<ID3D11Device>, wil::com_ptr<ID3D11DeviceContext>>
36createDevice(const wil::com_ptr<IDXGIAdapter> &adapter, u_logging_level log_level)
37{
38 D3D_DRIVER_TYPE driver_type = D3D_DRIVER_TYPE_HARDWARE;
39 if (adapter) {
40 // needed if we pass an adapter.
41 U_LOG_IFL_D(log_level, "Adapter provided.");
42 driver_type = D3D_DRIVER_TYPE_UNKNOWN;
43 }
44 unsigned int creation_flags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
45#ifndef NDEBUG
46 U_LOG_IFL_D(log_level, "Will attempt to create our device using the debug layer.");
47 creation_flags |= D3D11_CREATE_DEVICE_DEBUG;
48#endif
49
50 std::vector<D3D_FEATURE_LEVEL> feature_levels{D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0};
51 wil::com_ptr<ID3D11Device> device;
52 wil::com_ptr<ID3D11DeviceContext> context;
53 HRESULT hr = tryCreateDevice(adapter, driver_type, creation_flags, feature_levels, device, context);
54#ifndef NDEBUG
55 if (hr == DXGI_ERROR_SDK_COMPONENT_MISSING) {
56 U_LOG_IFL_D(log_level, "Removing the debug layer flag: not successful.");
57 creation_flags &= ~D3D11_CREATE_DEVICE_DEBUG;
58 hr = tryCreateDevice(adapter, driver_type, creation_flags, feature_levels, device, context);
59 }
60#endif
61 THROW_IF_FAILED(hr);
62 return {device, context};
63}
64} // namespace xrt::auxiliary::d3d::d3d11