【发布时间】:2020-08-16 11:34:40
【问题描述】:
我正在将我的代码从 D3D11 移植到 D3D12,并且我正在尝试在 D3D12 上获取显示器的刷新率。我使用刷新率来进行精确的动画计时(这是一个硬性要求)。此代码适用于 D3D11:
HRESULT GetRefreshRate(IUnknown* device, IDXGISwapChain* swapChain, double* outRefreshRate)
{
Microsoft::WRL::ComPtr<IDXGIOutput> dxgiOutput;
HRESULT hr = swapChain->GetContainingOutput(&dxgiOutput);
if (FAILED(hr))
return hr;
Microsoft::WRL::ComPtr<IDXGIOutput1> dxgiOutput1;
hr = dxgiOutput.As(&dxgiOutput1);
if (FAILED(hr))
return hr;
DXGI_MODE_DESC1 emptyMode = {};
DXGI_MODE_DESC1 modeDescription;
hr = dxgiOutput1->FindClosestMatchingMode1(&emptyMode, &modeDescription, device);
if (SUCCEEDED(hr))
*outRefreshRate = (double)modeDescription.RefreshRate.Numerator / (double)modeDescription.RefreshRate.Denominator;
return hr;
}
很遗憾,ID3D12Device 没有实现 IDXGIDevice 接口,因此 FindClosestMatchingMode1 失败并出现以下错误:
DXGI ERROR: IDXGIOutput::FindClosestMatchingMode: pConcernedDevice doesn't support the IDXGIDevice interface [ MISCELLANEOUS ERROR #69: ]
使用D3D12时有没有办法获取IDXGIDevice?或者,如何确定 D3D12 上的显示刷新率?
我知道EnumDisplaySettings 但是它返回一个整数,因此缺乏精度,导致动画漂移。我也找到了DwmGetCompositionTimingInfo,不过好像只支持获取主显示器的信息。
我还需要一种适用于传统 Win32 和 UWP 应用程序的解决方案。如果需要,我愿意为不同的应用程序模型使用两个代码路径。
【问题讨论】:
-
看来你正在开发UWP应用程序(DirectX 12 App (Universal Windows)),对吧?如果是,您可以添加UWP tag。
-
我需要这段代码在传统的 Win32 应用程序和 UWP 应用程序中工作(尽管如果需要我愿意有两个实现路径)。我查看了可用的 WinRT API 表面,但在这里没有看到任何有用的信息,因此我认为答案在 DXGI API 中的某个地方,并且在两种应用程序模型上都是相同的。我编辑了我的问题以澄清。
-
我可以重现这个问题。对于 Direct3D 12,您可以通过
IDXGISwapChain->GetDesc(),然后您将在DXGI_SWAP_CHAIN_DESC -> DXGI_MODE_DESC -> RefreshRate获得 RefreshRate。 -
@RitaHan-MSFT 我相信只有在首先创建交换链时设置刷新率才有效。在我的情况下它不起作用。看到这个:i.imgur.com/CLNY24N.png
-
我已经咨询了相关工程师以帮助解决这个问题,并会及时更新。
标签: c++ winapi directx direct3d12