🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

DXGI_SWAP_EFFECT_FLIP_DISCARD forces VSync?

Started by
2 comments, last by Juliean 1 year, 6 months ago

Hello,

so I had this weird bug where the builds of my game would run (relatively) slower than the editor-variant, even though it should perform way better. Long story short, a few months ago I ported to DX11.1, and by doing so, I followed the recommendation of swapping from DXGI_SWAP_EFFECT_DISCARD to DXGI_SWAP_EFFECT_FLIP_DISCARD (as I got a warning saying so every time I created the device). In the editor, I'm still using DXGI_SWAP_EFFECT_DISCARD as I'm rendering my entire GUI myself, and I only draw the parts that actually change (so using a flip-buffer would introduce artifacts).

Anyway, I noticed that DXGI_SWAP_EFFECT_FLIP_DISCARD somehow locks the FPS at my monitors refresh rate, even if I pass “false” to the vsync-parameter. Why does this lower my performance, you might ask? Well, thats a long story (which I lost yesterday due to the editor not autosaving, so I'll save the details - its definately something that should not happen when framerate is capped, so I'll look at it separately). However, I'm curious. Is this something normal? Do I have to do something differently to prevent FPS from locking up with flip-presentation-models? For reference, I'm using windowed-mode, and this is how I create the swap-chain:

const DXGI_SWAP_CHAIN_DESC1 swapDescription =
{
	.Width = displayMode.Width,
	.Height = displayMode.Height,
	.Format = displayMode.Format,
	.Stereo = false,
	.SampleDesc =
	{
		.Count = 1,
		.Quality = 0,
	},
	.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_SHADER_INPUT,
#ifndef AE_RUNTIME //! editor requires non-flip effect
	.BufferCount = 1,
	.Scaling = DXGI_SCALING_STRETCH,
	.SwapEffect = DXGI_SWAP_EFFECT_DISCARD,
#else
	.BufferCount = 2,
	.Scaling = DXGI_SCALING_NONE,
	.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD,
#endif
	.AlphaMode = DXGI_ALPHA_MODE_IGNORE
};

m_pDevice->SetupSwapchain_1_3(hWnd, *pFactory2, swapDescription);

and the call to present:

void Device::Present(void)
{
	if (m_pSwapChain1)
	{
		constexpr DXGI_PRESENT_PARAMETERS parameters = {};
		m_pSwapChain1->Present1(m_vsync, 0, &parameters); // for my tests, m_sync == false
	}
	else
		m_pSwapChain->Present(m_vsync, 0);
}
Advertisement

Here is why: Variable refresh rate displays - Win32 apps | Microsoft Learn

Here is how in DX11: KDBFootman/DirectXTutorial (github.com)

To disable vSync set to false the corresponding parameter of the Device's constructor.

class Device {

public:
	Device(DXGI_FORMAT backBufferFormat = DXGI_FORMAT_R8G8B8A8_UNORM, UINT backBufferCount = 2, D3D_FEATURE_LEVEL minFeatureLevel = D3D_FEATURE_LEVEL_10_0, bool vSync = true); // set true to disable vSync
	~Device() = default;
	
	 // ...
	 
} 

To

PAM79 said:
Here is why: Variable refresh rate displays - Win32 apps | Microsoft Learn

Thanks, this sounds exactly like what I need. I'm in the process of testing it out, but I do have two questions, perhaps you (or someone) know the answer as well?

  1. What happens if I set DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING and pass DXGI_PRESENT_ALLOW_TEARING without checking for hardware-support first; on a hardware that does not support it? Will it just ignore the flags, or will I get an error? Isn't clear just from documentation (it only says that you cannot pass DXGI_PRESENT_ALLOW_TEARING in fullscreen and without specifying the flag at creation; which I verified does result in errors)
  2. What versions of windows include DXGI1.5; which I would need to check for support?

I could always do the upcast to Factory1_5 to see if it exists, but I'd like to know if defaulting to using ALLOW_TEARING when on a PC where I don't know if its supported will do any harm.

This topic is closed to new replies.

Advertisement