Skip to content

Commit

Permalink
AtlasEngine: Add support for SetSoftwareRendering
Browse files Browse the repository at this point in the history
  • Loading branch information
lhecker committed Aug 30, 2022
1 parent 3ad0da8 commit eadb268
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 17 deletions.
5 changes: 5 additions & 0 deletions src/renderer/atlas/AtlasEngine.api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,11 @@ void AtlasEngine::SetSelectionBackground(const COLORREF color, const float alpha

void AtlasEngine::SetSoftwareRendering(bool enable) noexcept
{
if (_api.useSoftwareRendering != enable)
{
_api.useSoftwareRendering = enable;
WI_SetFlag(_api.invalidations, ApiInvalidations::Device);
}
}

void AtlasEngine::SetWarningCallback(std::function<void(HRESULT)> pfn) noexcept
Expand Down
41 changes: 24 additions & 17 deletions src/renderer/atlas/AtlasEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -578,39 +578,46 @@ void AtlasEngine::_createResources()
{
wil::com_ptr<ID3D11DeviceContext> deviceContext;

// Why D3D11_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS:
// This flag prevents the driver from creating a large thread pool for things like shader computations
// that would be advantageous for games. For us this has only a minimal performance benefit,
// but comes with a large memory usage overhead. At the time of writing the Nvidia
// driver launches $cpu_thread_count more worker threads without this flag.
static constexpr std::array driverTypes{
std::pair{ D3D_DRIVER_TYPE_HARDWARE, D3D11_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS },
std::pair{ D3D_DRIVER_TYPE_WARP, static_cast<D3D11_CREATE_DEVICE_FLAG>(0) },
};
static constexpr std::array featureLevels{
D3D_FEATURE_LEVEL_11_1,
D3D_FEATURE_LEVEL_11_0,
D3D_FEATURE_LEVEL_10_1,
};

auto hr = S_OK;
for (const auto& [driverType, additionalFlags] : driverTypes)
auto hr = E_UNEXPECTED;

if (!_api.useSoftwareRendering)
{
// Why D3D11_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS:
// This flag prevents the driver from creating a large thread pool for things like shader computations
// that would be advantageous for games. For us this has only a minimal performance benefit,
// but comes with a large memory usage overhead. At the time of writing the Nvidia
// driver launches $cpu_thread_count more worker threads without this flag.
hr = D3D11CreateDevice(
/* pAdapter */ nullptr,
/* DriverType */ driverType,
/* DriverType */ D3D_DRIVER_TYPE_HARDWARE,
/* Software */ nullptr,
/* Flags */ deviceFlags | additionalFlags,
/* Flags */ deviceFlags | D3D11_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS,
/* pFeatureLevels */ featureLevels.data(),
/* FeatureLevels */ gsl::narrow_cast<UINT>(featureLevels.size()),
/* SDKVersion */ D3D11_SDK_VERSION,
/* ppDevice */ _r.device.put(),
/* pFeatureLevel */ nullptr,
/* ppImmediateContext */ deviceContext.put());
}
if (FAILED(hr))
{
hr = D3D11CreateDevice(
/* pAdapter */ nullptr,
/* DriverType */ D3D_DRIVER_TYPE_WARP,
/* Software */ nullptr,
/* Flags */ deviceFlags,
/* pFeatureLevels */ featureLevels.data(),
/* FeatureLevels */ gsl::narrow_cast<UINT>(featureLevels.size()),
/* SDKVersion */ D3D11_SDK_VERSION,
/* ppDevice */ _r.device.put(),
/* pFeatureLevel */ nullptr,
/* ppImmediateContext */ deviceContext.put());
if (SUCCEEDED(hr))
{
break;
}
}
THROW_IF_FAILED(hr);

Expand Down
1 change: 1 addition & 0 deletions src/renderer/atlas/AtlasEngine.h
Original file line number Diff line number Diff line change
Expand Up @@ -1105,6 +1105,7 @@ namespace Microsoft::Console::Render

std::wstring customPixelShaderPath; // changes are flagged as ApiInvalidations::Device
bool useRetroTerminalEffect = false; // changes are flagged as ApiInvalidations::Device
bool useSoftwareRendering = false; // changes are flagged as ApiInvalidations::Device

ApiInvalidations invalidations = ApiInvalidations::Device;
} _api;
Expand Down

0 comments on commit eadb268

Please sign in to comment.