39 template <
typename BaseInterface, RENDER_DEVICE_TYPE DevType>
56 if (Adapters ==
nullptr)
57 NumAdapters =
static_cast<Uint32>(DXGIAdapters.size());
60 NumAdapters =
std::min(NumAdapters,
static_cast<Uint32>(DXGIAdapters.size()));
61 for (
Uint32 adapter = 0; adapter < NumAdapters; ++adapter)
63 IDXGIAdapter1* pDXIAdapter = DXGIAdapters[adapter];
64 DXGI_ADAPTER_DESC1 AdapterDesc;
65 pDXIAdapter->GetDesc1(&AdapterDesc);
67 auto& Attribs = Adapters[adapter];
71 Attribs.NumOutputs = 0;
72 CComPtr<IDXGIOutput> pOutput;
73 while (pDXIAdapter->EnumOutputs(Attribs.NumOutputs, &pOutput) != DXGI_ERROR_NOT_FOUND)
91 if (AdapterId >= DXGIAdapters.size())
93 LOG_ERROR(
"Incorrect adapter id ", AdapterId);
97 IDXGIAdapter1* pDXIAdapter = DXGIAdapters[AdapterId];
100 CComPtr<IDXGIOutput> pOutput;
101 if (pDXIAdapter->EnumOutputs(OutputId, &pOutput) == DXGI_ERROR_NOT_FOUND)
103 DXGI_ADAPTER_DESC1 AdapterDesc;
104 pDXIAdapter->GetDesc1(&AdapterDesc);
105 char DescriptionMB[
_countof(AdapterDesc.Description)];
106 WideCharToMultiByte(CP_ACP, 0, AdapterDesc.Description, -1, DescriptionMB,
_countof(DescriptionMB), NULL, FALSE);
107 LOG_ERROR_MESSAGE(
"Failed to enumerate output ", OutputId,
" of adapter ", AdapterId,
" (", DescriptionMB,
')');
113 auto hr = pOutput->GetDisplayModeList(DXIGFormat, 0, &numModes, NULL);
114 if (DisplayModes !=
nullptr)
117 std::vector<DXGI_MODE_DESC> DXIDisplayModes(numModes);
118 hr = pOutput->GetDisplayModeList(DXIGFormat, 0, &numModes, DXIDisplayModes.data());
121 const auto& SrcMode = DXIDisplayModes[m];
122 auto& DstMode = DisplayModes[m];
123 DstMode.
Width = SrcMode.Width;
124 DstMode.Height = SrcMode.Height;
126 DstMode.RefreshRateNumerator = SrcMode.RefreshRate.Numerator;
127 DstMode.RefreshRateDenominator = SrcMode.RefreshRate.Denominator;
128 DstMode.Scaling =
static_cast<SCALING_MODE>(SrcMode.Scaling);
129 DstMode.ScanlineOrder =
static_cast<SCANLINE_ORDER>(SrcMode.ScanlineOrdering);
131 NumDisplayModes =
std::min(NumDisplayModes, numModes);
135 NumDisplayModes = numModes;
142 std::vector<CComPtr<IDXGIAdapter1>> DXGIAdapters;
144 CComPtr<IDXGIFactory2> pFactory;
145 if (FAILED(CreateDXGIFactory1(__uuidof(IDXGIFactory2), (
void**)&pFactory)))
148 return std::move(DXGIAdapters);
151 CComPtr<IDXGIAdapter1> pDXIAdapter;
155 for (; pFactory->EnumAdapters1(adapter, &pDXIAdapter) != DXGI_ERROR_NOT_FOUND; ++adapter, pDXIAdapter.Release())
157 DXGI_ADAPTER_DESC1 AdapterDesc;
158 pDXIAdapter->GetDesc1(&AdapterDesc);
159 bool IsCompatibleAdapter = CheckAdapterCompatibility<DevType>(pDXIAdapter, d3dFeatureLevel);
160 if (IsCompatibleAdapter)
162 DXGIAdapters.emplace_back(std::move(pDXIAdapter));
166 return std::move(DXGIAdapters);
173 switch (FeatureLevel)
179 #if defined(_WIN32_WINNT_WIN10) && (_WIN32_WINNT >= _WIN32_WINNT_WIN10)
185 UNEXPECTED(
"Unknown DIRECT3D_FEATURE_LEVEL ",
static_cast<Uint32>(FeatureLevel));
186 return D3D_FEATURE_LEVEL_11_0;
191 template <RENDER_DEVICE_TYPE DevType>
192 bool CheckAdapterCompatibility(IDXGIAdapter1* pDXGIAdapter,
193 D3D_FEATURE_LEVEL FeatureLevels);
196 bool CheckAdapterCompatibility<RENDER_DEVICE_TYPE_D3D11>(IDXGIAdapter1* pDXGIAdapter,
197 D3D_FEATURE_LEVEL FeatureLevel)
199 auto hr = D3D11CreateDevice(
201 D3D_DRIVER_TYPE_NULL,
211 return SUCCEEDED(hr);
215 bool CheckAdapterCompatibility<RENDER_DEVICE_TYPE_D3D12>(IDXGIAdapter1* pDXGIAdapter,
216 D3D_FEATURE_LEVEL FeatureLevel)
218 auto hr =
D3D12CreateDevice(pDXGIAdapter, FeatureLevel, _uuidof(ID3D12Device),
nullptr);
219 return SUCCEEDED(hr);