From 2bcfb5b2e9cf5d08e7f26fa5514aa4225d31e493 Mon Sep 17 00:00:00 2001 From: Xu Date: Mon, 23 Dec 2024 00:53:21 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96=20GPU=20=E9=80=89?= =?UTF-8?q?=E6=8B=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Magpie.Core/DeviceResources.cpp | 67 +++++++++++++++----- src/Magpie.Core/DeviceResources.h | 10 +-- src/Magpie.Core/ImGuiImpl.cpp | 3 +- src/Magpie.Core/Renderer.cpp | 2 +- src/Magpie.Core/ScalingOptions.cpp | 9 ++- src/Magpie.Core/include/ScalingOptions.h | 12 +++- src/Magpie/AdaptersService.cpp | 79 ++++++++++++++++-------- src/Magpie/AdaptersService.h | 2 +- src/Magpie/AppSettings.cpp | 46 ++++++++++++-- src/Magpie/AppSettings.h | 2 +- src/Magpie/DirectXHelper.cpp | 52 ++++++++++++++++ src/Magpie/DirectXHelper.h | 10 +++ src/Magpie/Magpie.vcxproj | 2 + src/Magpie/Magpie.vcxproj.filters | 6 ++ src/Magpie/Profile.h | 29 +++++---- src/Magpie/ProfileViewModel.cpp | 53 ++++------------ src/Magpie/ProfileViewModel.h | 1 - src/Magpie/ScalingService.cpp | 2 +- 18 files changed, 267 insertions(+), 120 deletions(-) create mode 100644 src/Magpie/DirectXHelper.cpp create mode 100644 src/Magpie/DirectXHelper.h diff --git a/src/Magpie.Core/DeviceResources.cpp b/src/Magpie.Core/DeviceResources.cpp index 0818dd9d..c5d681b2 100644 --- a/src/Magpie.Core/DeviceResources.cpp +++ b/src/Magpie.Core/DeviceResources.cpp @@ -28,10 +28,10 @@ bool DeviceResources::Initialize() noexcept { Logger::Get().ComWarn("CheckFeatureSupport 失败", hr); } - _isSupportTearing = supportTearing; + _isTearingSupported = supportTearing; Logger::Get().Info(fmt::format("可变刷新率支持: {}", supportTearing ? "是" : "否")); - if (!_ObtainAdapterAndDevice(ScalingWindow::Get().Options().graphicsCard)) { + if (!_ObtainAdapterAndDevice(ScalingWindow::Get().Options().graphicsCardId)) { Logger::Get().Error("找不到可用的图形适配器"); return false; } @@ -64,31 +64,55 @@ ID3D11SamplerState* DeviceResources::GetSampler(D3D11_FILTER filterMode, D3D11_T return _samMap.emplace(key, std::move(sam)).first->second.get(); } -bool DeviceResources::_ObtainAdapterAndDevice(int adapterIdx) noexcept { +bool DeviceResources::_ObtainAdapterAndDevice(GraphicsCardId graphicsCardId) noexcept { winrt::com_ptr adapter; - if (adapterIdx >= 0) { - HRESULT hr = _dxgiFactory->EnumAdapters1(adapterIdx, adapter.put()); + if (graphicsCardId.idx >= 0) { + // 先使用索引 + HRESULT hr = _dxgiFactory->EnumAdapters1(graphicsCardId.idx, adapter.put()); if (SUCCEEDED(hr)) { DXGI_ADAPTER_DESC1 desc; hr = adapter->GetDesc1(&desc); if (SUCCEEDED(hr)) { - if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) { - Logger::Get().Warn("用户指定的显示卡为 WARP,已忽略"); - } else if (_TryCreateD3DDevice(adapter)) { - return true; + if (desc.VendorId == graphicsCardId.vendorId && desc.DeviceId == graphicsCardId.deviceId) { + if (_TryCreateD3DDevice(adapter)) { + return true; + } else { + Logger::Get().Warn("用户指定的显示卡不支持 FL 11"); + } } else { - Logger::Get().Warn("用户指定的显示卡不支持 FL 11"); + Logger::Get().Warn("显卡配置已变化"); } - } else { - Logger::Get().Error("GetDesc1 失败"); } - } else { - Logger::Get().Warn("未找到用户指定的显示卡"); + } + + // 枚举查找 vendorId 和 deviceId 匹配的显卡 + 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; + } + + Logger::Get().Warn("用户指定的显示卡不支持 FL11"); + break; + } + + ++adapterIndex; + if (adapterIndex == (UINT)graphicsCardId.idx) { + // 已经检查了 graphicsCardId.idx + ++adapterIndex; + } } } - // 枚举查找第一个支持 D3D11 的图形适配器 + // 枚举查找第一个支持 FL11 的显卡 for (UINT adapterIndex = 0; SUCCEEDED(_dxgiFactory->EnumAdapters1(adapterIndex, adapter.put())); ++adapterIndex @@ -109,7 +133,7 @@ bool DeviceResources::_ObtainAdapterAndDevice(int adapterIdx) noexcept { } } - // 作为最后手段,回落到 Basic Render Driver Adapter(WARP) + // 作为最后手段,回落到 CPU 渲染 (WARP) // https://docs.microsoft.com/en-us/windows/win32/direct3darticles/directx-warp HRESULT hr = _dxgiFactory->EnumWarpAdapter(IID_PPV_ARGS(&adapter)); if (FAILED(hr)) { @@ -187,10 +211,19 @@ bool DeviceResources::_TryCreateD3DDevice(const winrt::com_ptr& a _graphicsAdapter = adapter.try_as(); if (!_graphicsAdapter) { - Logger::Get().ComError("获取 IDXGIAdapter4 失败", hr); + Logger::Get().Error("获取 IDXGIAdapter4 失败"); return false; } + // 检查半精度浮点支持 + D3D11_FEATURE_DATA_SHADER_MIN_PRECISION_SUPPORT value; + hr = d3dDevice->CheckFeatureSupport(D3D11_FEATURE_SHADER_MIN_PRECISION_SUPPORT, &value, sizeof(value)); + if (SUCCEEDED(hr)) { + _isFP16Supported = value.AllOtherShaderStagesMinPrecision & D3D11_SHADER_MIN_PRECISION_16_BIT; + } else { + Logger::Get().ComError("CheckFeatureSupport 失败", hr); + } + return true; } diff --git a/src/Magpie.Core/DeviceResources.h b/src/Magpie.Core/DeviceResources.h index 26e72406..8fe2654b 100644 --- a/src/Magpie.Core/DeviceResources.h +++ b/src/Magpie.Core/DeviceResources.h @@ -1,5 +1,6 @@ #pragma once #include +#include "ScalingOptions.h" namespace Magpie { @@ -16,14 +17,14 @@ class DeviceResources { ID3D11DeviceContext4* GetD3DDC() const noexcept { return _d3dDC.get(); } IDXGIAdapter4* GetGraphicsAdapter() const noexcept { return _graphicsAdapter.get(); } - bool IsSupportTearing() const noexcept { - return _isSupportTearing; + bool IsTearingSupported() const noexcept { + return _isTearingSupported; } ID3D11SamplerState* GetSampler(D3D11_FILTER filterMode, D3D11_TEXTURE_ADDRESS_MODE addressMode) noexcept; private: - bool _ObtainAdapterAndDevice(int adapterIdx) noexcept; + bool _ObtainAdapterAndDevice(GraphicsCardId graphicsCardId) noexcept; bool _TryCreateD3DDevice(const winrt::com_ptr& adapter) noexcept; winrt::com_ptr _dxgiFactory; @@ -36,7 +37,8 @@ class DeviceResources { winrt::com_ptr > _samMap; - bool _isSupportTearing = false; + bool _isTearingSupported = false; + bool _isFP16Supported = false; }; } diff --git a/src/Magpie.Core/ImGuiImpl.cpp b/src/Magpie.Core/ImGuiImpl.cpp index 45205a9b..112386e2 100644 --- a/src/Magpie.Core/ImGuiImpl.cpp +++ b/src/Magpie.Core/ImGuiImpl.cpp @@ -26,13 +26,12 @@ bool ImGuiImpl::Initialize(DeviceResources* deviceResources) noexcept { Logger::Get().Error("ImGui 的头文件与链接库版本不同"); return false; } -#endif // _DEBUG +#endif ImGui::CreateContext(); // Setup backend capabilities flags ImGuiIO& io = ImGui::GetIO(); - io.BackendPlatformUserData = nullptr; io.BackendPlatformName = "Magpie"; io.ConfigFlags |= ImGuiConfigFlags_NavNoCaptureKeyboard | ImGuiConfigFlags_NoMouseCursorChange; diff --git a/src/Magpie.Core/Renderer.cpp b/src/Magpie.Core/Renderer.cpp index e70faf44..fce25667 100644 --- a/src/Magpie.Core/Renderer.cpp +++ b/src/Magpie.Core/Renderer.cpp @@ -190,7 +190,7 @@ bool Renderer::_CreateSwapChain() noexcept { .SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD, .AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED, // 只要显卡支持始终启用 DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING 以支持可变刷新率 - .Flags = UINT((_frontendResources.IsSupportTearing() ? DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING : 0) + .Flags = UINT((_frontendResources.IsTearingSupported() ? DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING : 0) | DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT) }; diff --git a/src/Magpie.Core/ScalingOptions.cpp b/src/Magpie.Core/ScalingOptions.cpp index b4bdc59d..3be6d06e 100644 --- a/src/Magpie.Core/ScalingOptions.cpp +++ b/src/Magpie.Core/ScalingOptions.cpp @@ -55,7 +55,10 @@ void ScalingOptions::Log() const noexcept { IsStatisticsForDynamicDetectionEnabled: {} IsTouchSupportEnabled: {} cropping: {},{},{},{} - graphicsCard: {} + graphicsCardId: + idx: {} + venderId: {} + deviceId: {} maxFrameRate: {} cursorScaling: {} captureMethod: {} @@ -80,7 +83,9 @@ void ScalingOptions::Log() const noexcept { IsStatisticsForDynamicDetectionEnabled(), IsTouchSupportEnabled(), cropping.Left, cropping.Top, cropping.Right, cropping.Bottom, - graphicsCard, + graphicsCardId.idx, + graphicsCardId.vendorId, + graphicsCardId.deviceId, maxFrameRate.has_value() ? *maxFrameRate : 0.0f, cursorScaling, (int)captureMethod, diff --git a/src/Magpie.Core/include/ScalingOptions.h b/src/Magpie.Core/include/ScalingOptions.h index 64e3c07a..33c4d211 100644 --- a/src/Magpie.Core/include/ScalingOptions.h +++ b/src/Magpie.Core/include/ScalingOptions.h @@ -28,6 +28,16 @@ struct Cropping { float Bottom; }; +// idx 为显卡索引,vendorId 和 deviceId 用于验证,如果不匹配则遍历显卡查找匹配。这可以处理显卡 +// 改变的情况,比如某些笔记本电脑可以在混合架构和独显直连之间切换。 +// idx 有两个作用,一是作为性能优化,二是用于区分同一型号的两个显卡。 +// idx 为 -1 表示使用默认显卡。 +struct GraphicsCardId { + int idx = -1; + uint32_t vendorId = 0; + uint32_t deviceId = 0; +}; + struct ScalingFlags { static constexpr uint32_t DisableWindowResizing = 1; static constexpr uint32_t BreakpointMode = 1 << 1; @@ -100,7 +110,7 @@ struct ScalingOptions { Cropping cropping{}; uint32_t flags = ScalingFlags::AdjustCursorSpeed | ScalingFlags::DrawCursor; // ScalingFlags - int graphicsCard = -1; + GraphicsCardId graphicsCardId; std::optional maxFrameRate; float cursorScaling = 1.0f; CaptureMethod captureMethod = CaptureMethod::GraphicsCapture; diff --git a/src/Magpie/AdaptersService.cpp b/src/Magpie/AdaptersService.cpp index fbb866b5..8d152e8a 100644 --- a/src/Magpie/AdaptersService.cpp +++ b/src/Magpie/AdaptersService.cpp @@ -11,6 +11,38 @@ using namespace winrt; namespace Magpie { bool AdaptersService::Initialize() noexcept { + com_ptr dxgiFactory; + + HRESULT hr = CreateDXGIFactory1(IID_PPV_ARGS(&dxgiFactory)); + if (FAILED(hr)) { + Logger::Get().ComError("CreateDXGIFactory1 失败", hr); + return false; + } + + com_ptr curAdapter; + for (UINT adapterIdx = 0; + SUCCEEDED(dxgiFactory->EnumAdapters1(adapterIdx, curAdapter.put())); + ++adapterIdx + ) { + DXGI_ADAPTER_DESC1 desc; + hr = curAdapter->GetDesc1(&desc); + if (FAILED(hr)) { + continue; + } + + // 不包含 WARP + if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) { + continue; + } + + _adapterInfos.push_back({ + .idx = adapterIdx, + .vendorId = desc.VendorId, + .deviceId = desc.DeviceId, + .description = desc.Description + }); + } + _monitorThread = std::thread(std::bind_front(&AdaptersService::_MonitorThreadProc, this)); return true; } @@ -35,7 +67,7 @@ void AdaptersService::Uninitialize() noexcept { _monitorThread.join(); } -void AdaptersService::_GatherAdapterInfos( +bool AdaptersService::_GatherAdapterInfos( com_ptr& dxgiFactory, wil::unique_event_nothrow& adaptersChangedEvent, DWORD& adaptersChangedCookie @@ -44,14 +76,14 @@ void AdaptersService::_GatherAdapterInfos( HRESULT hr = CreateDXGIFactory1(IID_PPV_ARGS(&dxgiFactory)); if (FAILED(hr)) { Logger::Get().ComError("CreateDXGIFactory1 失败", hr); - return; + return false; } hr = dxgiFactory->RegisterAdaptersChangedEvent( adaptersChangedEvent.get(), &adaptersChangedCookie); if (FAILED(hr)) { Logger::Get().ComError("RegisterAdaptersChangedEvent 失败", hr); - return; + return false; } std::vector adapterInfos; @@ -83,33 +115,22 @@ void AdaptersService::_GatherAdapterInfos( adapters.push_back(std::move(curAdapter)); } + wil::srwlock adapterInfosLock; + Win32Helper::RunParallel([&](uint32_t i) { + D3D_FEATURE_LEVEL fl = D3D_FEATURE_LEVEL_11_0; + if (FAILED(D3D11CreateDevice(adapters[i].get(), D3D_DRIVER_TYPE_UNKNOWN, + NULL, 0, &fl, 1, D3D11_SDK_VERSION, nullptr, nullptr, nullptr))) { + auto lock = adapterInfosLock.lock_exclusive(); + adapterInfos[i].isFL11Supported = false; + } + }, (uint32_t)adapters.size()); + App::Get().Dispatcher().RunAsync(CoreDispatcherPriority::Normal, [this, adapterInfos(std::move(adapterInfos))]() { _adapterInfos = std::move(adapterInfos); AdaptersChanged.Invoke(); }); - SmallVector noFL11Adapters; - { - wil::srwlock writeLock; - Win32Helper::RunParallel([&](uint32_t i) { - D3D_FEATURE_LEVEL fl = D3D_FEATURE_LEVEL_11_0; - if (FAILED(D3D11CreateDevice(adapters[i].get(), D3D_DRIVER_TYPE_UNKNOWN, - NULL, 0, &fl, 1, D3D11_SDK_VERSION, nullptr, nullptr, nullptr))) { - auto lock = writeLock.lock_exclusive(); - noFL11Adapters.push_back(i); - } - }, (uint32_t)adapters.size()); - } - - App::Get().Dispatcher().RunAsync(CoreDispatcherPriority::Normal, [this, noFL11Adapters(std::move(noFL11Adapters))]() { - for (uint32_t i : noFL11Adapters) { - _adapterInfos[i].isFL11Supported = false; - } - - if (!noFL11Adapters.empty()) { - AdaptersChanged.Invoke(); - } - }); + return true; } void AdaptersService::_MonitorThreadProc() noexcept { @@ -128,7 +149,9 @@ void AdaptersService::_MonitorThreadProc() noexcept { com_ptr dxgiFactory; DWORD adaptersChangedCookie = 0; - _GatherAdapterInfos(dxgiFactory, adaptersChangedEvent, adaptersChangedCookie); + if (!_GatherAdapterInfos(dxgiFactory, adaptersChangedEvent, adaptersChangedCookie)) { + return; + } while (true) { MSG msg; @@ -150,7 +173,9 @@ void AdaptersService::_MonitorThreadProc() noexcept { INFINITE, QS_ALLINPUT, MWMO_INPUTAVAILABLE) == WAIT_OBJECT_0) { // WAIT_OBJECT_0 表示显卡变化 // WAIT_OBJECT_0 + 1 表示有新消息 - _GatherAdapterInfos(dxgiFactory, adaptersChangedEvent, adaptersChangedCookie); + if (!_GatherAdapterInfos(dxgiFactory, adaptersChangedEvent, adaptersChangedCookie)) { + break; + } } } diff --git a/src/Magpie/AdaptersService.h b/src/Magpie/AdaptersService.h index 830e52dd..4a0495c0 100644 --- a/src/Magpie/AdaptersService.h +++ b/src/Magpie/AdaptersService.h @@ -37,7 +37,7 @@ class AdaptersService { private: AdaptersService() = default; - void _GatherAdapterInfos( + bool _GatherAdapterInfos( winrt::com_ptr& dxgiFactory, wil::unique_event_nothrow& adaptersChangedEvent, DWORD& adaptersChangedCookie diff --git a/src/Magpie/AppSettings.cpp b/src/Magpie/AppSettings.cpp index e2706f32..95e52187 100644 --- a/src/Magpie/AppSettings.cpp +++ b/src/Magpie/AppSettings.cpp @@ -16,6 +16,7 @@ #include "resource.h" #include "App.h" #include "MainWindow.h" +#include "DirectXHelper.h" using namespace winrt; using namespace winrt::Magpie; @@ -87,7 +88,14 @@ static void WriteProfile(rapidjson::PrettyWriter& write writer.Uint((uint32_t)profile.multiMonitorUsage); writer.Key("graphicsCard"); - writer.Int(profile.graphicsCard); + writer.StartObject(); + writer.Key("idx"); + writer.Int(profile.graphicsCardId.idx); + writer.Key("vendorId"); + writer.Uint(profile.graphicsCardId.vendorId); + writer.Key("deviceId"); + writer.Uint(profile.graphicsCardId.deviceId); + writer.EndObject(); writer.Key("frameRateLimiterEnabled"); writer.Bool(profile.isFrameRateLimiterEnabled); writer.Key("maxFrameRate"); @@ -792,11 +800,37 @@ bool AppSettings::_LoadProfile( profile.multiMonitorUsage = (MultiMonitorUsage)multiMonitorUsage; } - if (!JsonHelper::ReadInt(profileObj, "graphicsCard", profile.graphicsCard, true)) { - // v0.10.0-preview1 使用 graphicsAdapter - uint32_t graphicsAdater = 0; - JsonHelper::ReadUInt(profileObj, "graphicsAdapter", graphicsAdater); - profile.graphicsCard = (int)graphicsAdater - 1; + { + auto graphicsCardIdNode = profileObj.FindMember("graphicsCardId"); + if (graphicsCardIdNode == profileObj.end()) { + // v0.10 和 v0.11 只使用索引 + int graphicsCard = -1; + if (!JsonHelper::ReadInt(profileObj, "graphicsCard", graphicsCard, true)) { + // v0.10.0-preview1 使用 graphicsAdapter + uint32_t graphicsAdater = 0; + JsonHelper::ReadUInt(profileObj, "graphicsAdapter", graphicsAdater); + graphicsCard = (int)graphicsAdater - 1; + } + + profile.graphicsCardId = DirectXHelper::GetGraphicsCardIdFromIdx(graphicsCard); + } else if (graphicsCardIdNode->value.IsObject()) { + auto graphicsCardIdObj = graphicsCardIdNode->value.GetObj(); + + auto idxNode = graphicsCardIdObj.FindMember("idx"); + if (idxNode != graphicsCardIdObj.end() && idxNode->value.IsInt()) { + profile.graphicsCardId.idx = idxNode->value.GetInt(); + } + + auto vendorIdNode = graphicsCardIdObj.FindMember("vendorId"); + if (vendorIdNode != graphicsCardIdObj.end() && vendorIdNode->value.IsUint()) { + profile.graphicsCardId.vendorId = vendorIdNode->value.GetUint(); + } + + auto deviceIdNode = graphicsCardIdObj.FindMember("deviceId"); + if (deviceIdNode != graphicsCardIdObj.end() && deviceIdNode->value.IsUint()) { + profile.graphicsCardId.deviceId = deviceIdNode->value.GetUint(); + } + } } JsonHelper::ReadBool(profileObj, "frameRateLimiterEnabled", profile.isFrameRateLimiterEnabled); diff --git a/src/Magpie/AppSettings.h b/src/Magpie/AppSettings.h index e5026c5d..ffb524aa 100644 --- a/src/Magpie/AppSettings.h +++ b/src/Magpie/AppSettings.h @@ -267,7 +267,7 @@ class AppSettings : private _AppSettingsData { return _duplicateFrameDetectionMode; } - void DuplicateFrameDetectionMode(Magpie::DuplicateFrameDetectionMode value) noexcept { + void DuplicateFrameDetectionMode(enum DuplicateFrameDetectionMode value) noexcept { _duplicateFrameDetectionMode = value; SaveAsync(); } diff --git a/src/Magpie/DirectXHelper.cpp b/src/Magpie/DirectXHelper.cpp new file mode 100644 index 00000000..e346fa63 --- /dev/null +++ b/src/Magpie/DirectXHelper.cpp @@ -0,0 +1,52 @@ +#include "pch.h" +#include "DirectXHelper.h" +#include +#include + +using namespace winrt; + +namespace Magpie { + +GraphicsCardId DirectXHelper::GetGraphicsCardIdFromIdx(int idx) noexcept { + GraphicsCardId result; + + if (idx < 0) { + // 使用默认显卡 + return result; + } + + com_ptr dxgiFactory; + HRESULT hr = CreateDXGIFactory1(IID_PPV_ARGS(&dxgiFactory)); + if (FAILED(hr)) { + Logger::Get().ComError("CreateDXGIFactory1 失败", hr); + return result; + } + + com_ptr adapter; + hr = dxgiFactory->EnumAdapters1(idx, adapter.put()); + if (FAILED(hr)) { + // 可能因为该显卡已不存在 + Logger::Get().ComError("EnumAdapters1 失败", hr); + return result; + } + + DXGI_ADAPTER_DESC1 desc; + hr = adapter->GetDesc1(&desc); + if (FAILED(hr)) { + Logger::Get().ComError("GetDesc1 失败", hr); + return result; + } + + if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) { + // 不使用 WARP + return result; + } + + // 不检查 FL11,由 AdaptersService 检查 + result.idx = idx; + result.vendorId = desc.VendorId; + result.deviceId = desc.DeviceId; + return result; +} + +} diff --git a/src/Magpie/DirectXHelper.h b/src/Magpie/DirectXHelper.h new file mode 100644 index 00000000..1e1c56e1 --- /dev/null +++ b/src/Magpie/DirectXHelper.h @@ -0,0 +1,10 @@ +#pragma once +#include "Profile.h" + +namespace Magpie { + +struct DirectXHelper { + static GraphicsCardId GetGraphicsCardIdFromIdx(int idx) noexcept; +}; + +} diff --git a/src/Magpie/Magpie.vcxproj b/src/Magpie/Magpie.vcxproj index 290719fd..5967aa05 100644 --- a/src/Magpie/Magpie.vcxproj +++ b/src/Magpie/Magpie.vcxproj @@ -103,6 +103,7 @@ ControlSizeTrigger.idl Code + EffectParametersViewModel.idl @@ -286,6 +287,7 @@ ControlSizeTrigger.idl Code + EffectParametersViewModel.idl Code diff --git a/src/Magpie/Magpie.vcxproj.filters b/src/Magpie/Magpie.vcxproj.filters index 5393e671..4b7d9b58 100644 --- a/src/Magpie/Magpie.vcxproj.filters +++ b/src/Magpie/Magpie.vcxproj.filters @@ -76,6 +76,9 @@ Services + + Helpers + @@ -160,6 +163,9 @@ Services + + Helpers + diff --git a/src/Magpie/Profile.h b/src/Magpie/Profile.h index 0b387d50..9145768e 100644 --- a/src/Magpie/Profile.h +++ b/src/Magpie/Profile.h @@ -24,7 +24,7 @@ struct Profile { isCroppingEnabled = other.isCroppingEnabled; cropping = other.cropping; captureMethod = other.captureMethod; - graphicsCard = other.graphicsCard; + graphicsCardId = other.graphicsCardId; isFrameRateLimiterEnabled = other.isFrameRateLimiterEnabled; maxFrameRate = other.maxFrameRate; multiMonitorUsage = other.multiMonitorUsage; @@ -33,13 +33,13 @@ struct Profile { scalingFlags = other.scalingFlags; } - DEFINE_FLAG_ACCESSOR(IsWindowResizingDisabled, ::Magpie::ScalingFlags::DisableWindowResizing, scalingFlags) - DEFINE_FLAG_ACCESSOR(Is3DGameMode, ::Magpie::ScalingFlags::Is3DGameMode, scalingFlags) - DEFINE_FLAG_ACCESSOR(IsShowFPS, ::Magpie::ScalingFlags::ShowFPS, scalingFlags) - DEFINE_FLAG_ACCESSOR(IsCaptureTitleBar, ::Magpie::ScalingFlags::CaptureTitleBar, scalingFlags) - DEFINE_FLAG_ACCESSOR(IsAdjustCursorSpeed, ::Magpie::ScalingFlags::AdjustCursorSpeed, scalingFlags) - DEFINE_FLAG_ACCESSOR(IsDrawCursor, ::Magpie::ScalingFlags::DrawCursor, scalingFlags) - DEFINE_FLAG_ACCESSOR(IsDirectFlipDisabled, ::Magpie::ScalingFlags::DisableDirectFlip, scalingFlags) + DEFINE_FLAG_ACCESSOR(IsWindowResizingDisabled, ScalingFlags::DisableWindowResizing, scalingFlags) + DEFINE_FLAG_ACCESSOR(Is3DGameMode, ScalingFlags::Is3DGameMode, scalingFlags) + DEFINE_FLAG_ACCESSOR(IsShowFPS, ScalingFlags::ShowFPS, scalingFlags) + DEFINE_FLAG_ACCESSOR(IsCaptureTitleBar, ScalingFlags::CaptureTitleBar, scalingFlags) + DEFINE_FLAG_ACCESSOR(IsAdjustCursorSpeed, ScalingFlags::AdjustCursorSpeed, scalingFlags) + DEFINE_FLAG_ACCESSOR(IsDrawCursor, ScalingFlags::DrawCursor, scalingFlags) + DEFINE_FLAG_ACCESSOR(IsDirectFlipDisabled, ScalingFlags::DisableDirectFlip, scalingFlags) std::wstring name; @@ -54,21 +54,20 @@ struct Profile { CursorScaling cursorScaling = CursorScaling::NoScaling; float customCursorScaling = 1.0; - ::Magpie::Cropping cropping{}; + Cropping cropping{}; // -1 表示原样 int scalingMode = -1; - ::Magpie::CaptureMethod captureMethod = ::Magpie::CaptureMethod::GraphicsCapture; - // -1 表示默认,大于等于 0 为图形适配器的索引 - int graphicsCard = -1; - ::Magpie::MultiMonitorUsage multiMonitorUsage = ::Magpie::MultiMonitorUsage::Closest; - ::Magpie::CursorInterpolationMode cursorInterpolationMode = ::Magpie::CursorInterpolationMode::NearestNeighbor; + CaptureMethod captureMethod = CaptureMethod::GraphicsCapture; + GraphicsCardId graphicsCardId; + MultiMonitorUsage multiMonitorUsage = MultiMonitorUsage::Closest; + CursorInterpolationMode cursorInterpolationMode = CursorInterpolationMode::NearestNeighbor; // 10~1000 float maxFrameRate = 60.0f; std::wstring launchParameters; - uint32_t scalingFlags = ::Magpie::ScalingFlags::AdjustCursorSpeed | ::Magpie::ScalingFlags::DrawCursor; + uint32_t scalingFlags = ScalingFlags::AdjustCursorSpeed | ScalingFlags::DrawCursor; bool isPackaged = false; bool isCroppingEnabled = false; diff --git a/src/Magpie/ProfileViewModel.cpp b/src/Magpie/ProfileViewModel.cpp index a72ca348..788764a3 100644 --- a/src/Magpie/ProfileViewModel.cpp +++ b/src/Magpie/ProfileViewModel.cpp @@ -12,12 +12,12 @@ #include "AppSettings.h" #include "Logger.h" #include "ScalingMode.h" -#include #include "ScalingService.h" #include "FileDialogHelper.h" #include "CommonSharedConstants.h" #include "App.h" #include "MainWindow.h" +#include "AdaptersService.h" using namespace ::Magpie; using namespace winrt; @@ -28,34 +28,6 @@ using namespace Windows::UI::Xaml::Media::Imaging; namespace winrt::Magpie::implementation { -static SmallVector GetAllGraphicsCards() { - com_ptr dxgiFactory; - HRESULT hr = CreateDXGIFactory1(IID_PPV_ARGS(&dxgiFactory)); - if (FAILED(hr)) { - return {}; - } - - SmallVector result; - - com_ptr adapter; - for (UINT adapterIndex = 0; - SUCCEEDED(dxgiFactory->EnumAdapters1(adapterIndex, adapter.put())); - ++adapterIndex - ) { - DXGI_ADAPTER_DESC1 desc; - hr = adapter->GetDesc1(&desc); - - // 不包含 WARP - if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) { - continue; - } - - result.emplace_back(SUCCEEDED(hr) ? desc.Description : L"???"); - } - - return result; -} - ProfileViewModel::ProfileViewModel(int profileIdx) : _isDefaultProfile(profileIdx < 0) { if (_isDefaultProfile) { _data = &ProfileService::Get().DefaultProfile(); @@ -104,11 +76,6 @@ ProfileViewModel::ProfileViewModel(int profileIdx) : _isDefaultProfile(profileId _captureMethods = single_threaded_vector(std::move(captureMethods)); } - - _graphicsCards = GetAllGraphicsCards(); - if (_data->graphicsCard >= _graphicsCards.size()) { - _data->graphicsCard = -1; - } } ProfileViewModel::~ProfileViewModel() {} @@ -440,22 +407,26 @@ void ProfileViewModel::MultiMonitorUsage(int value) { IVector ProfileViewModel::GraphicsCards() const noexcept { std::vector graphicsCards; - graphicsCards.reserve(_graphicsCards.size() + 1); + + const std::vector& adapterInfos = AdaptersService::Get().AdapterInfos(); + graphicsCards.reserve(adapterInfos.size() + 1); ResourceLoader resourceLoader = ResourceLoader::GetForCurrentView(CommonSharedConstants::APP_RESOURCE_MAP_ID); hstring defaultStr = resourceLoader.GetString(L"Profile_General_CaptureMethod_Default"); graphicsCards.push_back(box_value(defaultStr)); - for (const std::wstring& graphicsCard : _graphicsCards) { - graphicsCards.push_back(box_value(graphicsCard)); + for (const AdapterInfo& adapterInfo : adapterInfos) { + graphicsCards.push_back(box_value(adapterInfo.description)); } return single_threaded_vector(std::move(graphicsCards)); } int ProfileViewModel::GraphicsCard() const noexcept { - return _data->graphicsCard + 1; + /*AdaptersService::Get().AdapterInfos() + return _data->graphicsCard + 1;*/ + return -1; } void ProfileViewModel::GraphicsCard(int value) { @@ -463,19 +434,19 @@ void ProfileViewModel::GraphicsCard(int value) { return; } - --value; + /*--value; if (_data->graphicsCard == value) { return; } _data->graphicsCard = value; - AppSettings::Get().SaveAsync(); + AppSettings::Get().SaveAsync();*/ RaisePropertyChanged(L"GraphicsCard"); } bool ProfileViewModel::IsShowGraphicsCardSettingsCard() const noexcept { - return _graphicsCards.size() > 1; + return AdaptersService::Get().AdapterInfos().size() > 1; } bool ProfileViewModel::IsFrameRateLimiterEnabled() const noexcept { diff --git a/src/Magpie/ProfileViewModel.h b/src/Magpie/ProfileViewModel.h index 53a95910..0fc3d1d6 100644 --- a/src/Magpie/ProfileViewModel.h +++ b/src/Magpie/ProfileViewModel.h @@ -151,7 +151,6 @@ struct ProfileViewModel : ProfileViewModelT, IVector _scalingModes{ nullptr }; IVector _captureMethods{ nullptr }; - ::Magpie::SmallVector _graphicsCards; uint32_t _index = 0; // 可以保存此指针的原因是: 用户停留在此页面时不会有缩放配置被创建或删除 diff --git a/src/Magpie/ScalingService.cpp b/src/Magpie/ScalingService.cpp index 1b2c2300..7397b92c 100644 --- a/src/Magpie/ScalingService.cpp +++ b/src/Magpie/ScalingService.cpp @@ -313,7 +313,7 @@ void ScalingService::_StartScale(HWND hWnd, const Profile& profile) { return; } - options.graphicsCard = profile.graphicsCard; + options.graphicsCardId = profile.graphicsCardId; options.captureMethod = profile.captureMethod; if (profile.isFrameRateLimiterEnabled) { options.maxFrameRate = profile.maxFrameRate;