简体   繁体   中英

Tearing with VSYNC in full screen mode only (windowed mode works fine) on Windows 10 / DirectX

I think that my DirectX 11 application worked fine on the previous system (I'm about 70% sure). But now, in Windows 10 (laptop) I have tearing issue in full screen mode only (the windowed mode works without any tearing).

The scene is quite "heavy" (it's supposed to be performance tested for my application). When DirectX renders "heavier" parts, it went down to about 50fps for a short time (my measurements may be a bit inaccurate) and then went back to 60-61fps. What is strange is, I do not not see tearing in the "heavier" parts (about 50fps).

I've heard that it can be somehow related to DWM which provides its own synchronization for windowed applications (that's why my program works fine in windowed mode?).

What can I do about it?

The swap chain:

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;

Where numerator and denominator are calculated based on this tutorial :

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

Which returns two very high values that gives about 60 when divided by each other (would I get the same effect by just setting them to 60 and 1 ?):

在此处输入图片说明

I also render with:

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

Did I miss something? Or did I do something wrong?

My comment as an answer:

Did you try to zero out the numerator and denominator? The DXGI will then calculate proper values automatically. ( doc ) The link also covers, why 60/1 shouldn't be hardcoded (can lead to problems on some systems).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM