【问题标题】:Tearing with VSYNC in full screen mode only (windowed mode works fine) on Windows 10 / DirectX在 Windows 10 / DirectX 上仅在全屏模式下使用 VSYNC 撕裂(窗口模式工作正常)
【发布时间】:2015-08-10 07:16:16
【问题描述】:

我认为我的 DirectX 11 应用程序在以前的系统上运行良好(我有 70% 的把握)。但现在,在 Windows 10(笔记本电脑)中 我仅在全屏模式下存在撕裂问题(窗口模式工作时不会出现任何撕裂)。

场景相当“繁重”(它应该为我的应用程序进行性能测试)。当 DirectX 渲染“较重”的部分时,它会在短时间内下降到大约 50fps(我的测量可能有点不准确),然后又回到 60-61fps。奇怪的是,我没有看到“较重”部分(约 50fps)出现撕裂。

我听说它可能与 DWM 相关,后者为窗口应用程序提供自己的同步(这就是为什么我的程序在窗口模式下工作正常?)。

我该怎么办?

交换链:

DXGI_SWAP_CHAIN_DESC sd;
ZeroMemory(&sd, sizeof(sd));
sd.BufferCount = 1;
sd.BufferDesc.Width = width;
sd.BufferDesc.Height = height;
sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
sd.BufferDesc.RefreshRate.Numerator = numerator;
sd.BufferDesc.RefreshRate.Denominator = denominator;
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
sd.OutputWindow = *hwnd;
sd.SampleDesc.Count = sampleCount; //1 (and 0 for quality) to turn off multisampling
sd.SampleDesc.Quality = maxQualityLevel;
sd.Windowed = fullScreen ? FALSE : TRUE;
sd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; //allow full-screen switchin

// Set the scan line ordering and scaling to unspecified.
sd.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
sd.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
// Discard the back buffer contents after presenting.
sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;

其中numeratordenominator是根据this tutorial计算的:

...
numerator = displayModeList[i].RefreshRate.Numerator;
denominator = displayModeList[i].RefreshRate.Denominator;

这会返回两个非常高的值,当它们彼此相除时,它们的值约为 60(如果将它们设置为 601,我会得到相同的效果吗?):

我也渲染:

if(VSYNC){
    swapChain->Present(1, 0); //lock to screen refresh rate
}else{
    swapChain->Present(0, 0); //present as fast as possible
}

我错过了什么吗?还是我做错了什么?

【问题讨论】:

  • 您是否尝试将分子和分母归零?然后 DXGI 将自动计算正确的值。 (msdn.microsoft.com/en-us/library/windows/desktop/…) 该链接还介绍了为什么不应该对 60/1 进行硬编码(可能会导致某些系统出现问题)。
  • @Gnietschow 我几乎可以肯定我不使用 DXGI(据我所知,我在我的 c++ 应用程序中只使用 DirectX 11,没有 DXGI,它对于某些任务来说是可选的“包装器”,但也许我错了)。无论如何,谢谢你的链接。我现在知道为什么不硬编码 60/1,但为什么我的计算方法会导致问题?我更喜欢 not 开始使用 DXGI 只是为了获取分子/分母值(复杂性等)。
  • DXGI 是用于处理 Windows Vista+ 的交换链和设备枚举的 API,并明确用于 Direct3D 10、11 和 12。您应该阅读这篇文章。
  • 我认为您将 DXGI 与 D3DX 辅助方法混淆了。正如 Chuck Walbourn 所说,您已经在使用 DXGI,因为它是 Direct3D、Direct2D、DirectWrite 等窗口中所有图形相关 api 的元 api。
  • @Gnietschow 确实,你是对的。并将事情设置为 0/0 来完成这项工作 - 你能从你的评论中得到答案吗?无论如何,为什么我获取这些值的方法(从教程中获取的方法)失败了?

标签: c++ directx directx-11 dwm vsync


【解决方案1】:

我的评论作为答案:

您是否尝试将分子和分母归零?然后 DXGI 将自动计算正确的值。 (doc) 该链接还介绍了为什么不应该对 60/1 进行硬编码(可能会导致某些系统出现问题)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-13
    • 2012-11-05
    • 2012-12-26
    相关资源
    最近更新 更多