Jump to content
  • Advertisement
Sign in to follow this  
Predator_MF

D3D9 Present() with VSYNC causing high CPU

This topic is 3735 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

I've posted this on other forums but I still don't have idea how to get over it in a right way. When I set my application to fullscreen with D3DPRESENT_INTERVAL_ONE (or another multiple vsync value), my renderloop consumes huge amount of CPU, even just for showing a black screen. I've tested this on few machines, it uses different amount of CPU depending on the CPU type, but it's still more than 30-40%, which is critical for my application - it uses VMR9 to render multiple videos, so it hungers for CPU time for the direct show decoders. When I turn vsync off, everything is running normal, except there's tearing on bigger videos. I thought vsync should be freeing more time for the CPU instead of making it slower.... Few people told me it's not really my app slowing CPU time, it's the Task manager that gives unreliable information...My dev system is running on 2.4GHz core2Duo mobile / nVidia 8600m GT, I'm watching the CPU usage in Process Explorer and a small OLED display above my keyboard, so I'm able to see CPU usage all the time, and I'm sure it's not task manager that lies about the CPU usage, plus when I can see bigger videos dropping frames, which means their decoders don't have enough CPU time to decode video streams. One way I tried to work around this is to add a Sleep(somevalue) right before calling Present, but the value there should differ on different PCs. Does anyone knows a clean solution to this problem ? Thanks, Pencheff

Share this post


Link to post
Share on other sites
Advertisement
There is very little information available online about the tool itself, but type perfmon into your Run dialog to get a proper performance monitor. Task Manager is a pretty lame tool for any sort of performance measurement.

Creating a manual swap chain (IDirect3DDevice9::CreateAdditionalSwapChain()) and then calling ::Present() with D3DPRESENT_DONOTWAIT might well be a useful avenue to explore. It'll return D3DERR_WASSTILLDRAWING if the GPU is too busy (can't queue up another frame) or is waiting on a VSYNC.

By default the behaviour is to busy-wait which is almost certainly the root cause of your problem. You could, if you really wanted re-implement this as:

while( D3DERR_WASSTILLDRAWING == pSwapChain->Present(NULL,NULL,NULL,NULL,D3DPRESENT_DONOTWAIT) );

But you could investigate putting in something like:

while( D3DERR_WASSTILLDRAWING == pSwapChain->Present(NULL,NULL,NULL,NULL,D3DPRESENT_DONOTWAIT) ) Sleep(1);

The Sleep() should then yield to any other processes briefly but still allow you to call ::Present() quickly once the state changes away from D3DERR_WASSTILLDRAWING...

hth
Jack

Share this post


Link to post
Share on other sites
Thanks Jack,
I was searching for a Direct3D alternative for DirectDraw's WaitForVerticalBlank(), I guess that will solve the problem, I'll try it tomorrow. I'm aware of perfmon, but it doesn't show anything different than Process Explorer or Task Manager, the CPU is really going high when I'm rendering at fullscreen (all the examples from SDK using DXUT library for example have this problem too). One of my "benchmarks" for the CPU when I'm on fullscreen is the videos that I'm rendering - VMR9 is dropping frames or stops rendering at all when CPU goes higher than 50%

Pencheff

Share this post


Link to post
Share on other sites
I'm having trouble using CreateAdditionalSwapChain(), as DirectX SDK docs say, I can't have two swap chains for fullscreen, so that means I can't create the additional swap chain with the same parameters that the default swap chain has. So I assume that I should use only the additional swap chain for calling Present, right ?

Share this post


Link to post
Share on other sites
Quote:
So I assume that I should use only the additional swap chain for calling Present, right ?
Yes, this is what I had in mind.

Quote:
I'm aware of perfmon, but it doesn't show anything different than Process Explorer or Task Manager
It does offer much more granular detail - sure, its not perfect, but being able to break down across multiple CPU's/Cores is an instant win over TaskMan. The real big difference, albeit not relevant here, is the memory monitoring for which TaskMan is simply not an option.


hth
Jack

Share this post


Link to post
Share on other sites
Making additional swapchain for the same window in fullscreen makes my application hang (or triggering a breakpoint in my code which I cannot catch...I don't have second monitor around). I guess there could not be two devices or windows working at the same time in fullscreen, so that's why it does it.

I can't exactly figure out how am I supposed to use the additional swapchain in my fullscreen application. The problem is:

while( D3DERR_WASSTILLDRAWING == m_pTestSwapChain->Present(NULL,NULL,NULL,NULL,D3DPRESENT_DONOTWAIT) ) Sleep(1);

will execute as soon as my monitor starts new vertical blank, executing this code shows some erratic picture on screen, probably it's fliping me a backbuffer that I'm not working with ? I'm not that experienced to tell...

I need more help on this, please :)

Share this post


Link to post
Share on other sites
hmm, yes I can remember this being a little tricky for exactly the reasons you state.

Unfortunately I'm not at my dev machine right now and won't be until tomorrow evening so I can't have a dig around in my old code or documents. Sorry.

From a quick look on MSDN it might be worth experimenting with creating the device in windowed mode and then calling IDirect3DDevice9::CreateAdditionalSwapChain() with your fullscreen configuration.

Quote:
will execute as soon as my monitor starts new vertical blank, executing this code shows some erratic picture on screen, probably it's fliping me a backbuffer that I'm not working with ? I'm not that experienced to tell...
Fire up the debug runtimes and if you start getting bright pink/green flashes instead of garbage then your diagnosis is correct.

You may also want to do some reading around the swap effect enumeration in your D3DPRESENT_PARAMETERS struct. This can influence the flipping/swapping behaviour.

hth
Jack

Share this post


Link to post
Share on other sites
You can use IDirect3DDevice9::GetSwapChain to get the swap chain interface for the swap chains that were created during device creation.

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!