perf: 避免重复尝试创建 D3D 设备

This commit is contained in:
Xu 2024-12-25 13:05:01 +08:00
commit 4f481e4ec5
9 changed files with 46 additions and 32 deletions

View file

@ -66,8 +66,12 @@ ID3D11SamplerState* DeviceResources::GetSampler(D3D11_FILTER filterMode, D3D11_T
bool DeviceResources::_ObtainAdapterAndDevice(GraphicsCardId graphicsCardId) noexcept {
winrt::com_ptr<IDXGIAdapter1> adapter;
// 记录不支持 FL11 的显卡索引,防止重复尝试
int failedIdx = -1;
if (graphicsCardId.idx >= 0) {
assert(graphicsCardId.vendorId != 0 && graphicsCardId.deviceId != 0);
// 先使用索引
HRESULT hr = _dxgiFactory->EnumAdapters1(graphicsCardId.idx, adapter.put());
if (SUCCEEDED(hr)) {
@ -77,47 +81,57 @@ bool DeviceResources::_ObtainAdapterAndDevice(GraphicsCardId graphicsCardId) noe
if (desc.VendorId == graphicsCardId.vendorId && desc.DeviceId == graphicsCardId.deviceId) {
if (_TryCreateD3DDevice(adapter)) {
return true;
} else {
Logger::Get().Warn("用户指定的显示卡不支持 FL 11");
}
failedIdx = graphicsCardId.idx;
Logger::Get().Warn("用户指定的显示卡不支持 FL 11");
} else {
Logger::Get().Warn("显卡配置已变化");
}
}
}
// 枚举查找 vendorId 和 deviceId 匹配的显卡
assert(graphicsCardId.vendorId != 0 && graphicsCardId.deviceId != 0);
UINT adapterIndex = graphicsCardId.idx == 0 ? 1 : 0;
while (SUCCEEDED(_dxgiFactory->EnumAdapters1(adapterIndex, adapter.put()))) {
DXGI_ADAPTER_DESC1 desc;
hr = adapter->GetDesc1(&desc);
if (FAILED(hr)) {
continue;
}
if (desc.VendorId == graphicsCardId.vendorId && desc.DeviceId == graphicsCardId.deviceId) {
if (_TryCreateD3DDevice(adapter)) {
return true;
// 如果已确认该显卡不支持 FL11不再重复尝试
if (failedIdx == -1) {
// 枚举查找 vendorId 和 deviceId 匹配的显卡
for (UINT adapterIdx = 0;
SUCCEEDED(_dxgiFactory->EnumAdapters1(adapterIdx, adapter.put()));
++adapterIdx
) {
if ((int)adapterIdx == graphicsCardId.idx) {
// 已经检查了 graphicsCardId.idx
continue;
}
Logger::Get().Warn("用户指定的显示卡不支持 FL11");
break;
}
DXGI_ADAPTER_DESC1 desc;
hr = adapter->GetDesc1(&desc);
if (FAILED(hr)) {
continue;
}
++adapterIndex;
if (adapterIndex == (UINT)graphicsCardId.idx) {
// 已经检查了 graphicsCardId.idx
++adapterIndex;
if (desc.VendorId == graphicsCardId.vendorId && desc.DeviceId == graphicsCardId.deviceId) {
if (_TryCreateD3DDevice(adapter)) {
return true;
}
failedIdx = (int)adapterIdx;
Logger::Get().Warn("用户指定的显示卡不支持 FL11");
break;
}
}
}
}
// 枚举查找第一个支持 FL11 的显卡
for (UINT adapterIndex = 0;
SUCCEEDED(_dxgiFactory->EnumAdapters1(adapterIndex, adapter.put()));
++adapterIndex
for (UINT adapterIdx = 0;
SUCCEEDED(_dxgiFactory->EnumAdapters1(adapterIdx, adapter.put()));
++adapterIdx
) {
if ((int)adapterIdx == failedIdx) {
// 无需再次尝试
continue;
}
DXGI_ADAPTER_DESC1 desc;
HRESULT hr = adapter->GetDesc1(&desc);
if (FAILED(hr) || DirectXHelper::IsWARP(desc)) {

View file

@ -190,7 +190,7 @@ bool App::Initialize(const wchar_t* arguments) {
// 有的设备上后台调用 D3D11CreateDevice 会拖累主窗口显示速度,因此应在主窗口显示后
// 再检查显卡的功能级别。
((RootPage::base_type&)*_mainWindow->Content()).Loaded([](const auto&, const auto&) {
_mainWindow->Content()->Loaded([](const auto&, const auto&) {
// 低优先级回调确保在初始化完毕后执行
App::Get().Dispatcher().RunAsync(CoreDispatcherPriority::Low, []() {
AdaptersService::Get().StartMonitor();

View file

@ -62,7 +62,7 @@ bool MainWindow::Create() noexcept {
(sizeToSet.cx == 0 ? (SWP_NOMOVE | SWP_NOSIZE) : 0) | SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOCOPYBITS);
// Xaml 控件加载完成后显示主窗口
((RootPage::base_type&)*Content()).Loaded([this, isMaximized](winrt::IInspectable const&, winrt::RoutedEventArgs const&) {
Content()->Loaded([this, isMaximized](winrt::IInspectable const&, winrt::RoutedEventArgs const&) {
if (isMaximized) {
// ShowWindow(Handle(), SW_SHOWMAXIMIZED) 会显示错误的动画。因此我们以窗口化显示,
// 但位置和大小都和最大化相同,显示完毕后将状态设为最大化。

View file

@ -86,7 +86,7 @@ void RootPage::InitializeComponent() {
}
}
void RootPage::Loaded(IInspectable const&, RoutedEventArgs const&) {
void RootPage::RootPage_Loaded(IInspectable const&, RoutedEventArgs const&) {
// 消除焦点框
IsTabStop(true);
Focus(FocusState::Programmatic);

View file

@ -17,7 +17,7 @@ struct RootPage : RootPageT<RootPage> {
void InitializeComponent();
void Loaded(IInspectable const&, RoutedEventArgs const&);
void RootPage_Loaded(IInspectable const&, RoutedEventArgs const&);
void NavigationView_SelectionChanged(MUXC::NavigationView const&, MUXC::NavigationViewSelectionChangedEventArgs const& args);

View file

@ -5,7 +5,7 @@
xmlns:local="using:Magpie"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
Loaded="Loaded"
Loaded="RootPage_Loaded"
mc:Ignorable="d">
<Grid>
<local:TitleBarControl x:Name="TitleBar"

View file

@ -32,7 +32,7 @@ TitleBarControl::TitleBarControl() {
}(this);
}
void TitleBarControl::Loading(FrameworkElement const&, IInspectable const&) {
void TitleBarControl::TitleBarControl_Loading(FrameworkElement const&, IInspectable const&) {
MUXC::NavigationView rootNavigationView = App::Get().RootPage()->RootNavigationView();
rootNavigationView.DisplayModeChanged([this](const auto&, const auto& args) {
bool expanded = args.DisplayMode() == MUXC::NavigationViewDisplayMode::Expanded;

View file

@ -9,7 +9,7 @@ struct TitleBarControl : TitleBarControlT<TitleBarControl>,
wil::notify_property_changed_base<TitleBarControl> {
TitleBarControl();
void Loading(FrameworkElement const&, IInspectable const&);
void TitleBarControl_Loading(FrameworkElement const&, IInspectable const&);
Imaging::SoftwareBitmapSource Logo() const noexcept {
return _logo;

View file

@ -8,7 +8,7 @@
Height="40"
HorizontalAlignment="Stretch"
VerticalAlignment="Top"
Loading="Loading"
Loading="TitleBarControl_Loading"
mc:Ignorable="d">
<Grid>
<local:SimpleStackPanel Margin="16,10,0,0"