The open source OpenXR runtime
at prediction-2 100 lines 2.9 kB view raw
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 <wil/com.h> 16#include <wil/result.h> 17 18#include <vector> 19 20namespace xrt::auxiliary::d3d { 21template <typename T> 22static wil::com_ptr<T> 23try_create_dxgi_factory() 24{ 25 26 wil::com_ptr<T> factory; 27 LOG_IF_FAILED(CreateDXGIFactory1(__uuidof(T), factory.put_void())); 28 29 return factory; 30} 31 32wil::com_ptr<IDXGIAdapter> 33getAdapterByIndex(uint16_t index, u_logging_level log_level) 34{ 35 36 wil::com_ptr<IDXGIAdapter> ret; 37 auto factory6 = try_create_dxgi_factory<IDXGIFactory6>(); 38 if (factory6 != nullptr) { 39 U_LOG_IFL_I(log_level, "Using IDXGIFactory6::EnumAdapterByGpuPreference to select adapter to use."); 40 LOG_IF_FAILED(factory6->EnumAdapterByGpuPreference(index, DXGI_GPU_PREFERENCE_HIGH_PERFORMANCE, 41 __uuidof(IDXGIAdapter), ret.put_void())); 42 if (ret) { 43 return ret; 44 } 45 // Otherwise fall through to the other factory 46 } 47 48 auto factory = try_create_dxgi_factory<IDXGIFactory>(); 49 if (factory != nullptr) { 50 U_LOG_IFL_I(log_level, 51 "IDXGIFactory6 unavailable, using IDXGIFactory::EnumAdapters to select adapter to use."); 52 LOG_IF_FAILED(factory->EnumAdapters(index, ret.put())); 53 return ret; 54 } 55 return ret; 56} 57 58wil::com_ptr<IDXGIAdapter> 59getAdapterByLUID(const xrt_luid_t &luid, u_logging_level log_level) 60{ 61 LUID realLuid = reinterpret_cast<const LUID &>(luid); 62 wil::com_ptr<IDXGIAdapter> ret; 63 auto factory4 = try_create_dxgi_factory<IDXGIFactory4>(); 64 if (factory4 != nullptr) { 65 U_LOG_IFL_I(log_level, "Using IDXGIFactory4::EnumAdapterByLuid to select adapter to use."); 66 LOG_IF_FAILED(factory4->EnumAdapterByLuid(realLuid, __uuidof(IDXGIAdapter), ret.put_void())); 67 if (ret) { 68 return ret; 69 } 70 // Otherwise fall through to the other factory 71 } 72 73 // This basically is manual implementation of EnumAdapterByLuid 74 auto factory1 = try_create_dxgi_factory<IDXGIFactory1>(); 75 if (factory1 != nullptr) { 76 U_LOG_IFL_I(log_level, 77 "IDXGIFactory6 unavailable, using IDXGIFactory1::EnumAdapters1 to select adapter to use."); 78 for (unsigned int i = 0;; ++i) { 79 80 wil::com_ptr<IDXGIAdapter1> adapter; 81 if (!SUCCEEDED(factory1->EnumAdapters1(i, adapter.put()))) { 82 U_LOG_IFL_W(log_level, 83 "Ran out of adapters using IDXGIFactory1::EnumAdapters1 before finding a " 84 "matching LUID."); 85 break; 86 } 87 DXGI_ADAPTER_DESC1 desc{}; 88 if (!SUCCEEDED(adapter->GetDesc1(&desc))) { 89 continue; 90 } 91 if (realLuid.HighPart == desc.AdapterLuid.HighPart && 92 realLuid.LowPart == desc.AdapterLuid.LowPart) { 93 ret = adapter; 94 break; 95 } 96 } 97 } 98 return ret; 99} 100} // namespace xrt::auxiliary::d3d