2

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?):

enter image description here

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?

Wandering Fool
  • 2,170
  • 3
  • 18
  • 48
PolGraphic
  • 3,233
  • 11
  • 51
  • 108
  • Did you try to zero out the numerator and denominator? The DXGI will then calculate proper values automatically. (https://msdn.microsoft.com/en-us/library/windows/desktop/ee417025(v=vs.85).aspx) The link also covers, why 60/1 shouldn't be hardcoded (can lead to problems on some systems). – Gnietschow Aug 01 '15 at 23:35
  • @Gnietschow I am almost sure I don't use DXGI (as far as I know I use just DirectX 11 in my c++ application, without DXGI which is optional "wrapper" for some tasks, but maybe I'm wrong). Anyway, thank you for the link. I know now why not to hardcode 60/1, but why my approach of calculating it does cause problems? I prefer **not** to start using DXGI just to get numerator/denominator values (complexity etc.). – PolGraphic Aug 02 '15 at 10:59
  • DXGI is the API that handles the swapchain and device enumeration for Windows Vista+ and is used explicitly with Direct3D 10, 11, and 12. You should read the article. – Chuck Walbourn Aug 02 '15 at 21:28
  • 1
    I think you're confusing the DXGI with the D3DX helper methods. As Chuck Walbourn said, you're already using DXGI, because its the meta api for all graphic relevant api's in windows like Direct3D, Direct2D, DirectWrite etc. – Gnietschow Aug 04 '15 at 22:11
  • @Gnietschow Indeed, you're right. And setting things to 0/0 do the job - can you make an answer from your comment? Anyway, why my method of getting those values (the one that has been taken from the tutorial) fails me? – PolGraphic Aug 04 '15 at 22:59
  • Unfortunately I have no idea. I also tried to get the refresh rate of the adapter, but it didn't worked properly until I used the automatic 0/0. Maybe someone else can enlighten us :) – Gnietschow Aug 09 '15 at 21:43
  • Syncing to an arbitrary framerate of a display device ("Vsync") is a **basic** function of computer graphics that must be *easily* supported and enforceable by all APIs and frameworks on all platforms using any language for development, and should also be the default. We have not evolved, and this is madness. All this is to say I sympathize while also wondering how we got to this point. – Henrik Erlandsson Sep 08 '17 at 23:24
  • Vsync was understood in the 1960s, used in the 1970s, in 1981 we took a wrong turn and non CG people made graphics cards, in the 90s analog displays still held on and there was a return until DVI and beyond where this apparently isn't understood as a basic function again. This ends my historical review, I promise. – Henrik Erlandsson Sep 08 '17 at 23:33

1 Answers1

1

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).

Gnietschow
  • 3,070
  • 1
  • 18
  • 28