Add a fallback to software rendering (#1263)

This commit enables a software rendering fallback for the DX renderer in the case that hardware acceleration fails. This is primarily useful for Hyper-V environments where hardware acceleration is not guaranteed to exist.

This will be useful for future work to enable the DX renderer to run on windows 7 since win7 virtual machines do not/cannot have hardware acceleration unlike windows 10 machines

This commit does two things:
- Fallback to `D3D_DRIVER_TYPE_WARP` if `D3D_DRIVER_TYPE_HARDWARE` fails.
- pass `NULL` as the adapter instead of creating the default adapter ourselves.
This commit is contained in:
Daniel Griffen 2019-06-24 17:02:26 -07:00 committed by Dustin L. Howett (MSFT)
parent bc236c7c59
commit b9e66fee6d
2 changed files with 26 additions and 17 deletions

View file

@ -130,8 +130,6 @@ DxEngine::~DxEngine()
RETURN_IF_FAILED(CreateDXGIFactory1(IID_PPV_ARGS(&_dxgiFactory2)));
RETURN_IF_FAILED(_dxgiFactory2->EnumAdapters1(0, &_dxgiAdapter1));
const DWORD DeviceFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT |
// clang-format off
// This causes problems for folks who do not have the whole DirectX SDK installed
@ -154,18 +152,33 @@ DxEngine::~DxEngine()
D3D_FEATURE_LEVEL_9_1,
};
RETURN_IF_FAILED(D3D11CreateDevice(_dxgiAdapter1.Get(),
D3D_DRIVER_TYPE_UNKNOWN,
NULL,
DeviceFlags,
FeatureLevels,
ARRAYSIZE(FeatureLevels),
D3D11_SDK_VERSION,
&_d3dDevice,
NULL,
&_d3dDeviceContext));
// Trying hardware first for maximum performance, then trying WARP (software) renderer second
// in case we're running inside a downlevel VM where hardware passthrough isn't enabled like
// for Windows 7 in a VM.
const auto hardwareResult = D3D11CreateDevice(NULL,
D3D_DRIVER_TYPE_HARDWARE,
NULL,
DeviceFlags,
FeatureLevels,
ARRAYSIZE(FeatureLevels),
D3D11_SDK_VERSION,
&_d3dDevice,
NULL,
&_d3dDeviceContext);
RETURN_IF_FAILED(_dxgiAdapter1->EnumOutputs(0, &_dxgiOutput));
if (FAILED(hardwareResult))
{
RETURN_IF_FAILED(D3D11CreateDevice(NULL,
D3D_DRIVER_TYPE_WARP,
NULL,
DeviceFlags,
FeatureLevels,
ARRAYSIZE(FeatureLevels),
D3D11_SDK_VERSION,
&_d3dDevice,
NULL,
&_d3dDeviceContext));
}
_displaySizePixels = _GetClientSize();
@ -309,7 +322,6 @@ void DxEngine::_ReleaseDeviceResources() noexcept
_dxgiSurface.Reset();
_dxgiSwapChain.Reset();
_dxgiOutput.Reset();
if (nullptr != _d3dDeviceContext.Get())
{
@ -321,7 +333,6 @@ void DxEngine::_ReleaseDeviceResources() noexcept
_d3dDevice.Reset();
_dxgiAdapter1.Reset();
_dxgiFactory2.Reset();
}

View file

@ -156,9 +156,7 @@ namespace Microsoft::Console::Render
bool _haveDeviceResources;
::Microsoft::WRL::ComPtr<ID3D11Device> _d3dDevice;
::Microsoft::WRL::ComPtr<ID3D11DeviceContext> _d3dDeviceContext;
::Microsoft::WRL::ComPtr<IDXGIAdapter1> _dxgiAdapter1;
::Microsoft::WRL::ComPtr<IDXGIFactory2> _dxgiFactory2;
::Microsoft::WRL::ComPtr<IDXGIOutput> _dxgiOutput;
::Microsoft::WRL::ComPtr<IDXGISurface> _dxgiSurface;
::Microsoft::WRL::ComPtr<ID2D1RenderTarget> _d2dRenderTarget;
::Microsoft::WRL::ComPtr<ID2D1SolidColorBrush> _d2dBrushForeground;