feat: 记录 D3D 设备能力

修复编译错误
光标插值选项默认值改为 Bicubic
This commit is contained in:
Xu 2026-03-16 12:47:02 +08:00
commit 1fd6a9d5f3
7 changed files with 154 additions and 66 deletions

View file

@ -82,8 +82,9 @@ def remove_file(file):
pass
for file in glob.glob("*.lib", ".exp"):
remove_file(file)
for pattern in ["*.lib", "*.exp"]:
for file in glob.glob(pattern):
remove_file(file)
print("清理完毕", flush=True)

View file

@ -50,18 +50,25 @@ bool D3D12Context::Initialize(
{
D3D12_FEATURE_DATA_ROOT_SIGNATURE featureData = { .HighestVersion = D3D_ROOT_SIGNATURE_VERSION_1_1 };
hr = _device->CheckFeatureSupport(D3D12_FEATURE_ROOT_SIGNATURE, &featureData, sizeof(featureData));
if (FAILED(hr)) {
if (SUCCEEDED(hr)) {
_rootSignatureVersion = featureData.HighestVersion;
} else {
Logger::Get().ComError("CheckFeatureSupport 失败", hr);
return false;
}
_rootSignatureVersion = featureData.HighestVersion;
}
// 检查是否是集成显卡
{
D3D12_FEATURE_DATA_ARCHITECTURE1 data{};
if (SUCCEEDED(_device->CheckFeatureSupport(D3D12_FEATURE_ARCHITECTURE1, &data, sizeof(data)))) {
hr = _device->CheckFeatureSupport(D3D12_FEATURE_ARCHITECTURE1, &data, sizeof(data));
if (SUCCEEDED(hr)) {
_isUMA = data.UMA;
} else {
Logger::Get().ComError("CheckFeatureSupport 失败", hr);
return false;
}
}
@ -73,11 +80,31 @@ bool D3D12Context::Initialize(
// 检查 Resizable BAR 支持
{
D3D12_FEATURE_DATA_D3D12_OPTIONS16 data{};
if (SUCCEEDED(_device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS16, &data, sizeof(data)))) {
hr = _device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS16, &data, sizeof(data));
if (SUCCEEDED(hr)) {
_isGPUUploadHeapSupported = data.GPUUploadHeapSupported;
} else {
Logger::Get().ComError("CheckFeatureSupport 失败", hr);
return false;
}
}
// 检查 FP16 支持
{
D3D12_FEATURE_DATA_D3D12_OPTIONS data{};
HRESULT hr = _device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS, &data, sizeof(data));
if (SUCCEEDED(hr)) {
_isFP16Supported = data.MinPrecisionSupport & D3D12_SHADER_MIN_PRECISION_SUPPORT_16_BIT;
} else {
Logger::Get().ComError("CheckFeatureSupport 失败", hr);
return false;
}
}
_LogDeviceInfo();
if (!_InitializeDeviceResources(
maxInFlightFrameCount, priority, commandListType, disableFrameFenceTracking)) {
Logger::Get().Error("_InitializeDeviceResources 失败");
@ -96,6 +123,7 @@ void D3D12Context::CopyDevice(const D3D12Context& other) {
_isUMA = other._isUMA;
_isHeapFlagCreateNotZeroedSupported = other._isHeapFlagCreateNotZeroedSupported;
_isGPUUploadHeapSupported = other._isGPUUploadHeapSupported;
_isFP16Supported = other._isFP16Supported;
}
bool D3D12Context::InitializeAfterCopyDevice(
@ -406,61 +434,23 @@ bool D3D12Context::_CreateAdapterAndDevice(const GraphicsCardId& graphicsCardId)
return true;
}
bool D3D12Context::_TryCreateD3DDevice(const winrt::com_ptr<IDXGIAdapter1>& adapter, const DXGI_ADAPTER_DESC1& adapterDesc) noexcept {
bool D3D12Context::_TryCreateD3DDevice(
const winrt::com_ptr<IDXGIAdapter1>& adapter,
const DXGI_ADAPTER_DESC1& adapterDesc
) noexcept {
HRESULT hr = D3D12CreateDevice(adapter.get(), D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&_device));
if (FAILED(hr)) {
Logger::Get().ComError("D3D12CreateDevice 失败", hr);
return false;
}
{
D3D_FEATURE_LEVEL featureLevels[] = {
D3D_FEATURE_LEVEL_12_2,
D3D_FEATURE_LEVEL_12_1,
D3D_FEATURE_LEVEL_12_0,
D3D_FEATURE_LEVEL_11_1,
D3D_FEATURE_LEVEL_11_0
};
D3D12_FEATURE_DATA_FEATURE_LEVELS featureData{
.NumFeatureLevels = (UINT)std::size(featureLevels),
.pFeatureLevelsRequested = featureLevels
};
hr = _device->CheckFeatureSupport(D3D12_FEATURE_FEATURE_LEVELS, &featureData, sizeof(featureData));
if (SUCCEEDED(hr)) {
std::string_view flStr;
switch (featureData.MaxSupportedFeatureLevel) {
case D3D_FEATURE_LEVEL_12_2:
flStr = "12.2";
break;
case D3D_FEATURE_LEVEL_12_1:
flStr = "12.1";
break;
case D3D_FEATURE_LEVEL_12_0:
flStr = "12.0";
break;
case D3D_FEATURE_LEVEL_11_1:
flStr = "11.1";
break;
case D3D_FEATURE_LEVEL_11_0:
flStr = "11.0";
break;
default:
flStr = "未知";
break;
}
Logger::Get().Info(fmt::format("已创建 D3D12 设备\n\t功能级别: {}", flStr));
} else {
Logger::Get().ComError("CheckFeatureSupport 失败", hr);
}
}
_dxgiAdapter = adapter.try_as<IDXGIAdapter4>();
if (!_dxgiAdapter) {
Logger::Get().Error("获取 IDXGIAdapter4 失败");
return false;
}
Logger::Get().Info(fmt::format("当前图形适配器: \n\tVendorId: {:#x}\n\tDeviceId: {:#x}\n\tDescription: {}",
Logger::Get().Info(fmt::format("图形适配器\n\tVendorId: {:#x}\n\tDeviceId: {:#x}\n\tDescription: {}",
adapterDesc.VendorId, adapterDesc.DeviceId, StrHelper::UTF16ToUTF8(adapterDesc.Description)));
return true;
@ -538,4 +528,105 @@ bool D3D12Context::_QueryHighestShaderModel() noexcept {
return false;
}
void D3D12Context::_LogDeviceInfo() noexcept {
std::string_view featureLevel;
{
D3D_FEATURE_LEVEL featureLevels[] = {
D3D_FEATURE_LEVEL_12_2,
D3D_FEATURE_LEVEL_12_1,
D3D_FEATURE_LEVEL_12_0,
D3D_FEATURE_LEVEL_11_1,
D3D_FEATURE_LEVEL_11_0
};
D3D12_FEATURE_DATA_FEATURE_LEVELS featureData = {
.NumFeatureLevels = (UINT)std::size(featureLevels),
.pFeatureLevelsRequested = featureLevels
};
HRESULT hr = _device->CheckFeatureSupport(
D3D12_FEATURE_FEATURE_LEVELS, &featureData, sizeof(featureData));
if (SUCCEEDED(hr)) {
switch (featureData.MaxSupportedFeatureLevel) {
case D3D_FEATURE_LEVEL_12_2:
featureLevel = "12.2";
break;
case D3D_FEATURE_LEVEL_12_1:
featureLevel = "12.1";
break;
case D3D_FEATURE_LEVEL_12_0:
featureLevel = "12.0";
break;
case D3D_FEATURE_LEVEL_11_1:
featureLevel = "11.1";
break;
case D3D_FEATURE_LEVEL_11_0:
featureLevel = "11.0";
break;
default:
featureLevel = "未知";
break;
}
} else {
Logger::Get().ComError("CheckFeatureSupport 失败", hr);
featureLevel = "未知";
}
}
std::string_view shaderModel;
switch (_shaderModel) {
case D3D_SHADER_MODEL_6_9:
shaderModel = "6.9";
break;
case D3D_SHADER_MODEL_6_8:
shaderModel = "6.8";
break;
case D3D_SHADER_MODEL_6_7:
shaderModel = "6.7";
break;
case D3D_SHADER_MODEL_6_6:
shaderModel = "6.6";
break;
case D3D_SHADER_MODEL_6_5:
shaderModel = "6.5";
break;
case D3D_SHADER_MODEL_6_4:
shaderModel = "6.4";
break;
case D3D_SHADER_MODEL_6_3:
shaderModel = "6.3";
break;
case D3D_SHADER_MODEL_6_2:
shaderModel = "6.2";
break;
case D3D_SHADER_MODEL_6_1:
shaderModel = "6.1";
break;
case D3D_SHADER_MODEL_6_0:
shaderModel = "6.0";
break;
default:
shaderModel = "5.1";
break;
}
constexpr const char* boolStrs[] = { "","" };
Logger::Get().Info(fmt::format(R"(已创建 D3D12 设备
: {}
shader model : {}
: {}
: {}
D3D12_HEAP_FLAG_CREATE_NOT_ZEROED : {}
Resizable BAR : {}
FP16 : {})",
featureLevel,
shaderModel,
_rootSignatureVersion == D3D_ROOT_SIGNATURE_VERSION_1_1 ? "1.1" : "1.0",
boolStrs[_isUMA],
boolStrs[_isHeapFlagCreateNotZeroedSupported],
boolStrs[_isGPUUploadHeapSupported],
boolStrs[_isFP16Supported]
));
}
}

View file

@ -76,6 +76,10 @@ public:
return _isGPUUploadHeapSupported;
}
bool IsFP16Supported() const noexcept {
return _isFP16Supported;
}
uint32_t GetMaxInFlightFrameCount() const noexcept {
return (uint32_t)_commandAllocators.size();
}
@ -107,12 +111,17 @@ private:
bool _CreateAdapterAndDevice(const GraphicsCardId& graphicsCardId) noexcept;
bool _TryCreateD3DDevice(const winrt::com_ptr<IDXGIAdapter1>& adapter, const DXGI_ADAPTER_DESC1& adapterDesc) noexcept;
bool _TryCreateD3DDevice(
const winrt::com_ptr<IDXGIAdapter1>& adapter,
const DXGI_ADAPTER_DESC1& adapterDesc
) noexcept;
bool _CreateAdapterFromDevice() noexcept;
bool _QueryHighestShaderModel() noexcept;
void _LogDeviceInfo() noexcept;
DescriptorHeap* _csuDescriptorHeap = nullptr;
DescriptorHeap* _rtvDescriptorHeap = nullptr;
@ -136,6 +145,7 @@ private:
bool _isUMA = false;
bool _isHeapFlagCreateNotZeroedSupported = false;
bool _isGPUUploadHeapSupported = false;
bool _isFP16Supported = false;
};
}

View file

@ -21,18 +21,6 @@ bool EffectsDrawer::Initialize(
ID3D12Device5* device = d3d12Context.GetDevice();
// 检查半精度浮点支持
{
D3D12_FEATURE_DATA_D3D12_OPTIONS featureData{};
HRESULT hr = device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS, &featureData, sizeof(featureData));
if (SUCCEEDED(hr)) {
_isFP16Supported = featureData.MinPrecisionSupport & D3D12_SHADER_MIN_PRECISION_SUPPORT_16_BIT;
Logger::Get().Info(StrHelper::Concat("FP16 支持: ", _isFP16Supported ? "" : ""));
} else {
Logger::Get().ComError("CheckFeatureSupport 失败", hr);
}
}
if (ScalingWindow::Get().Options().IsWindowedMode()) {
_outputSize = rendererSize;
} else {

View file

@ -1,6 +1,5 @@
#pragma once
#include "CatmullRomDrawer.h"
#include "SmallVector.h"
namespace Magpie {
@ -49,7 +48,6 @@ private:
UINT64 _timestampFrequency = 0;
bool _isScRGB = false;
bool _isFP16Supported = false;
};
}

View file

@ -218,7 +218,7 @@ struct ScalingOptions {
CaptureMethod captureMethod = CaptureMethod::GraphicsCapture;
MultiMonitorUsage multiMonitorUsage = MultiMonitorUsage::Closest;
OutputAlignment outputAlignment = OutputAlignment::Center;
CursorInterpolationMode cursorInterpolationMode = CursorInterpolationMode::NearestNeighbor;
CursorInterpolationMode cursorInterpolationMode = CursorInterpolationMode::Bicubic;
std::optional<float> autoHideCursorDelay;
DuplicateFrameDetectionMode duplicateFrameDetectionMode = DuplicateFrameDetectionMode::Dynamic;
uint32_t maxProducerInFlightFrames = 2;

View file

@ -89,7 +89,7 @@ struct Profile {
CaptureMethod captureMethod = CaptureMethod::GraphicsCapture;
GraphicsCardId graphicsCardId;
MultiMonitorUsage multiMonitorUsage = MultiMonitorUsage::Closest;
CursorInterpolationMode cursorInterpolationMode = CursorInterpolationMode::NearestNeighbor;
CursorInterpolationMode cursorInterpolationMode = CursorInterpolationMode::Bicubic;
// 10~1000
float maxFrameRate = 60.0f;