Archived

This topic is now archived and is closed to further replies.

Kjell Andersson

Surface flipping on multiple monitors

Recommended Posts

I have a DirectX/3D application that uses a multi monitor setup. The problem is that I seem to have trouble synchronizing the surface-flips for both displays. Sometimes the application works just fine, but other times the application runs as half the FPS. The problem seem to be that after the first screen has waited for the vsync and then flipped, the second flip will wait for yet another vsync before it flips. This causes the FPS to drop to half the rate of which it could be. My application uses the old Flip() call in DirectX < 8. I just saw the documentation for DX8 where Flip() has been outdated and a new concept of SwapChains has been introduced. Anyone know if these swap chains are more multi-monitor reliable than Flip(). If not, have anyone had the same Flip() problems as me or know what might solve my problem?

Share this post


Link to post
Share on other sites
Try passing the NOVSYNC flag.

Pass it to all but one of the monitors. So that the first one synchronises to it''s monitors refresh rate, and the rest flip whenever they can. Or alternatively use multiple threads (one per monitor) so that while one is blocked waiting for it''s monitors flip to syncronise to the vertical blanking gap, the others can flip if they''re ready.

If you''re currently single threaded and doing:

Render a frame to all monitors
Flip(monitor1, WAIT)
Flip(monitor2, WAIT)
Flip(monitor3, WAIT)
...

then the whole frame will be synced to the slowest card (which''ll be any PCI cards in the system). Worse still, if the frame of rendering on the first monitor takes almost all of the refresh rate of that monitor (say 59Hz on a 60Hz monitor), when you come to the next monitor, that monitor could have just had it''s VSYNC, so you have to wait all over again...

The DX8 flags and chains are an improvement, but most of what they offer can be done by passing flags such as NOVSYNC to Flip

--
Simon O''''Connor
Creative Asylum Ltd
www.creative-asylum.com

Share this post


Link to post
Share on other sites
The problem with only synchronizing to one of the screens is that the other screen get flickers when it flips. You get a visual distortion between the previous frame and the new one at some point on the NOVSYNC screen.

I have tried your other approach, using two different threads for the screens. That approach does not work either. When the threads are waiting for their flip to occur they seem to be scheduled so that one of the threads misses its vsync becuase the other thread is stealing all CPU polling its vsync. This gives a condition where only one of the screens updates and the other then have to wait for yet another vsync.

How is the multimonitor support in DirectX really meant to work? The example that comes with DirectX synchronizes both screens. This must be wrong since it gives a total maximum rendering time less than the difference betweeen the vsyncs of the screens until it can no longer run in full framerate.

The optimal approach, that I can see, would be if the rendering loops were connected to interrupts. After the rendering is done, you instruct the display to give you an interrupt when the flip occurs. This interrupt then in reality executes the rendering. This way there would be no problem with multithreading the whole application and the CPU would not be loaded to 100% just waiting for a vsync.

Share this post


Link to post
Share on other sites
I have gained more insight into how Windows NT/2000/XP schedules its threads now.

On Window NT Workstation, a thread initially has a time quantum of 6. Each time NT receives a clock interrupt (tick), it subtracts a value of 3 from the remaining quantum of the active thread. A clock interrupt is generated every 15 milliseconds, so the default time slice given to a normal thread is 30 milliseconds. I don''t think this has changed much for Windows 2000/XP. This means that a CPU-consuming thread that uses its full quanta will interfere with another thread for 30 milliseconds. If we then have two processes waiting for vsync, one of them will not be interrupted in its search for vsync. If the thread, that did not run, actually had its vsync before the other thread it will miss it, causing that tread to wait for the next vsync.

All this means that since the time quanta of Windows is so high, multithreading a realtime DirectX-application is not possible.

Share this post


Link to post
Share on other sites