Skip to content

Commit

Permalink
Add a fallback to software rendering (#1263)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
ZoeyR authored and DHowett committed Jun 25, 2019
1 parent bc236c7 commit b9e66fe
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 18 deletions.
43 changes: 27 additions & 16 deletions src/renderer/dx/DxRenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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));

RETURN_IF_FAILED(_dxgiAdapter1->EnumOutputs(0, &_dxgiOutput));
// 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);

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();

Expand Down Expand Up @@ -309,7 +322,6 @@ void DxEngine::_ReleaseDeviceResources() noexcept

_dxgiSurface.Reset();
_dxgiSwapChain.Reset();
_dxgiOutput.Reset();

if (nullptr != _d3dDeviceContext.Get())
{
Expand All @@ -321,7 +333,6 @@ void DxEngine::_ReleaseDeviceResources() noexcept

_d3dDevice.Reset();

_dxgiAdapter1.Reset();
_dxgiFactory2.Reset();
}

Expand Down
2 changes: 0 additions & 2 deletions src/renderer/dx/DxRenderer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit b9e66fe

Please sign in to comment.