Jump to content
  • Advertisement
Sign in to follow this  
zalbard

Swap chain latency reduction & waiting before the 1st Present

This topic is 830 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi everyone,
 
the MSDN article "Reduce latency with DXGI 1.3 swap chains" discusses a latency reduction technique for swap chains which involves waitable objects.
 
The idea is clear to me. I would like to clarify one aspect, though. Please see the comment in the source code below:
 

// Block this thread until the swap chain is finished presenting. Note that it is
// important to call this before the first Present in order to minimize the latency
// of the swap chain.
m_deviceResources->WaitOnSwapChain();

 
How exactly does waiting before the first Present() minimize the latency?
 
And does it matter when to wait before the first Present()? Can it be done right after creating the swap chain?
 
Details are appreciated. Thanks!

Share this post


Link to post
Share on other sites
Advertisement

from:

 

https://msdn.microsoft.com/en-us/library/windows/apps/mt210781.aspx

 

When the rendering loop calls Present(), the system blocks the thread until it is done presenting a prior frame, making room to queue up the new frame, before it actually presents. This causes extra latency between the time the game draws a frame and the time the system allows it to display that frame. In many cases, the system will reach a stable equilibrium where the game is always waiting almost a full extra frame between the time it renders and the time it presents each frame. It's better to wait until the system is ready to accept a new frame, then render the frame based on current data and queue the frame immediately. "

 

 

it appears that present() does not return from being called until the current/previous frame has been rendered. so there may be some lag between when you call present() and when it actually presents.

 

so the idea is DX tells the game when it ready for the next call to present(). i guess the ideas is you run update (with a "fix your timestep" algo most likely) until DX says its ready for the next call to present(), at which point you call render().

 

not sure how useful it would be.  if your framerate is high, the lag is low. and "fix your timestep" lags by half a frame on average all the time anyway.

 

OTOH, it does mean that render will present the scene with the latest possible update info.  but if you have "fix your timestep", your already sacrificing accuracy for smoother animation.

 

i personally favor accuracy and use lower framerates, which gives more time for render and update.

Share this post


Link to post
Share on other sites

I've had another look at the documentation. In particular, I believe this sentence offers a better wording/explanation:

 

Swap chains created this way can notify your rendering loop when the system is actually ready to accept a new frame.

 

Which, I suppose, includes two cases:

  • finished the swap chain setup (in the case of the first Present());
  • finished presenting the previous frame.

Thanks!

Share this post


Link to post
Share on other sites

odds are waitOnSwapChain sets a flag to indicate whether dx should tell the game when its ready for the next frame or not, and that flag only gets set if the swap chain has been created, but present() has not been called yet. at least that would yield the described behavior - even if the internal workings of DX differ somewhat. this sort of makes since, because some sort of "i'm ready for a frame" code would have to be enabled in the pipeline - most likely affecting present().  and enabling and disabling that capability on the fly is most likely problematic, thus the requirement to do it one time upfront before the first call to present().

 

once you use Dx for a while, you start to understand how they build things (think 50's mainframe code <g>), and why things work the way they do.

Share this post


Link to post
Share on other sites

Sorry for the necro post, just registered and I was skimming through some older posts and saw this one didn't have a proper answer.

 

Anyway, to answer your question about this:
The object that you wait on for the waitable object swapchain is a semaphore. Let's say that you say "I want 1 frame of latency, please." Then we give the semaphore a starting value of 1. If you go ahead and call Present() and do something else for a while, then when that frame completes, it'll signal the semaphore to let you know there's more room in the pipeline. If you didn't wait on the semaphore first, this will end up bumping the semaphore up to 2. Then you can very quickly issue commands for 2 frames, and suddenly your latency is 2 frames, even though you said you only wanted 1.
 
In other words, the waitable object only works when you wait on it before every present, including the first one.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!