internal override bool TryGetAdapterByIndex(uint index, out Adapter adapter) { // We only set this to true in TryOrderByPreference which checks we have IDXGIFactory6 so we can hard cast _factory if (_enumByPreference) { while (true) { using UniqueComPtr <IDXGIAdapter1> dxgiAdapter = default; Guard.ThrowIfFailed( _factory.Ptr->EnumAdapterByGpuPreference( index + _skipAdapterOffset, // DXGI preference doesn't allow preferring hardware/software adapters, so we do that manually after filtering out the other hardware types // We remove the hardware and software flag so DXGI doesn't complain (DXGI_GPU_PREFERENCE)(_preference & ~(DevicePreference.Hardware | DevicePreference.Software)), dxgiAdapter.Iid, (void **)&dxgiAdapter ) ); // null adapter means we have reached end of list if (!dxgiAdapter.Exists) { adapter = default; return(false); } // if it only supports hardware of software, we have to filter them out. If both or neither are set, we allow all adapters through if (_preference.HasFlag(DevicePreference.Hardware) != _preference.HasFlag(DevicePreference.Software)) { DXGI_ADAPTER_DESC1 desc; Guard.ThrowIfFailed(dxgiAdapter.Ptr->GetDesc1(&desc)); bool isHardware = (desc.Flags & (int)DXGI_ADAPTER_FLAG.DXGI_ADAPTER_FLAG_SOFTWARE) == 0; // If they want hardware but we don't have it, or they want software and we don't have it, skip this adapter if (_preference.HasFlag(DevicePreference.Hardware) != isHardware) { _skipAdapterOffset++; continue; } } adapter = CreateAdapter(dxgiAdapter.Move()); return(true); } } else { using UniqueComPtr <IDXGIAdapter1> dxgiAdapter = default; Guard.ThrowIfFailed(_factory.Ptr->EnumAdapters1(index, ComPtr.GetAddressOf(&dxgiAdapter))); adapter = CreateAdapter(dxgiAdapter.Move()); return(true); } }
public override bool TryEnablePreferentialOrdering(DevicePreference preference) { DXCoreAdapterPreference *pPreferences = stackalloc DXCoreAdapterPreference[4]; int i = 0; _softwareOnly = preference.HasFlag(DevicePreference.Software) && !preference.HasFlag(DevicePreference.Hardware); if (!TryAdd(DevicePreference.Hardware, DXCoreAdapterPreference.Hardware)) { return(false); } if (!TryAdd(DevicePreference.LowPower, DXCoreAdapterPreference.MinimumPower)) { return(false); } if (!TryAdd(DevicePreference.HighPerformance, DXCoreAdapterPreference.HighPerformance)) { return(false); } Guard.ThrowIfFailed(_list.Ptr->Sort((uint)i, pPreferences)); return(true); bool TryAdd(DevicePreference devicePref, DXCoreAdapterPreference dxCorePref) { if (!preference.HasFlag(devicePref)) { return(true); } if (!_list.Ptr->IsAdapterPreferenceSupported(dxCorePref)) { return(false); } StackSentinel.StackAssert(i < 4); pPreferences[i++] = dxCorePref; return(true); } }