Best threading model for DX10 multiple monitor non full screen app?

Started by
3 comments, last by CliveJarman 12 years, 1 month ago
I have currently porting a DX9 based XP application to DX10 on Windows 7.

This application displays scrolling data in multiple windows on multiple monitors (up to 4 monitors, with 3 windows per monitor). Each present must by synced to the VSYNC of the monitor as it is important that we have no tearing. It is not a full screen DirectX app.

In the current architecture (XP with DirectX 9) a different DirectX 9 device was created for each monitor and each monitor had its own rendering thread (not the main thread). A separate swap chain was created for each window. Each rendering thread would render to each window in turn, and then present to each window in turn, i.e. RenderA, RenderB, RenderC, PresentA, PresentB, PresentC. This worked well in XP with DirectX9.

The problem is that this arrangement does not seem to work well in Windows 7 with DirectX 10. I have ported the Render Code to DX10, and am using DXGI swap chains.I now need help choosing the threading model.

It seems that DXGI swap chains work a lot differently than DX9 swap chains. For a start, in order to present synced to the VSYNC, It seems that I MUST enable the Desktop Windows Manager (i.e. Aero). If I do not do this, only one window on the monitor updates per monitor refresh (a different window each refresh). This means that for the 3 windows WindowA, WindowB, WindowC, you will get WindowA updated on frame1, WindowB on frame 2, WindowC on frame 3, and Window A on frame 4. This effectively gives a refresh rate of 20Hz for each window on a 60Hz monitor - yuck!

Enabling DWM has caused some performance problems, as now each window's content is now blitted to a DWM surface each frame. The real problem that I am running into is that the scrolling of each window's content is no longer smooth using the existing threading model of one rendering thread per monitor. I experimented with reducing the number of monitors, and got good results only when I had one monitor (i.e. only one rendering thread)

What is the best way to render multiple windows synced to the VSYNC to multiple monitors with DirectX10?
Thanks,
Clive
Advertisement
I haven't experimented yet with multiple swapchains in Direct3D 10/11 yet, only dx9 ...

But what do you get when you only use 1 Direct3D Device and 1 render thread and you present your swapchains in a loop with the PRESENT_DO_NOT_WAIT flag? (And you just keep trying to present when they return the "i'm still drawing" return flag)? smile.png

In dx9 the big trick in order to have no tearing in windowed mode is to lock/unlock the backbuffer (or copy a small piece to system memory), I hope we don't need to this anymore in dx10/dx11 but if you are hopeless...
Thats interesting. You mentioned locking/unlocking the backbuffer.
In the original XP application, I was writing on the backbuffer with GDI every frame (and I guess this will lock/unlock the backbuffer)
In my DirectX10 version, I am using Direct2D instead of GDI. So no more backbuffer locking!
I'll try manually locking/unlocking it and post results tomorrow.
I tried locking the backbuffer (by doing a GDI bitblit onto a small section).
The results were a bit better than before, but there were still noticeable stuttering in frame rate.

Wouldn't locking the backbuffer cause me to sync the CPU with the GPU every frame?
Wouldn't that mean that I would have to render everything within 16ms or else miss a frame?

I guess I am a little confused as to how locking the backbuffer would help.
Bump!Anyone got any feedback on this issue?

This topic is closed to new replies.

Advertisement