2

I'm a newbie on Direct3D9 and trying some stuff. I wish to use 'WaitForVSync' on a 'IDirect3DDevice9Ex' device. However, I have no clue how to use it and get VSYNC interrupts. I couldn't find much help on MSDN nor any code snippet. Any help would be appreciated.

Thanks, Mots

mots_g
  • 637
  • 8
  • 27
  • D3D9Ex you mean... this is an API that is only available in Windows 7+. You already have the function to do this, that function puts the calling thread to sleep and waits for the D3D runtime to signal an event when the next VBlank interrupt rolls around. The runtime can take care of multimedia class scheduling since it knows the thread is waiting for a graphics-related event. – Andon M. Coleman Aug 16 '16 at 01:01

2 Answers2

1

This code will allow you to call a function (to do your interrupt) during a vertical blank period. I would not recommend this because of timing issues. By the time you figure out you are in the vertical blank period, it might be over. You can try to account for this if you know your target hardware, but you will have to calculate the latency of the function call experimentally. I recommend not using a VSYNC callback. Here is the code to do it anyway.

D3DRASTER_STATUS rStatus;  
pd3dDevice->GetRasterStatus(0, &rStatus);

while (rStatus.InVBlank)
{
  Sleep(0); // Ensure other threads get CPU time.
  pd3dDevice->GetRasterStatus(0, &rStatus);
}

// Should be in a vertical blank period. Call your function here.
MyFunction();
  • Woah, don't use `Sleep (0)` to ensure other threads get CPU time :) This likely will not do anything, the render thread probably already has a higher thread priority than anything waiting... the thread goes onto the wait list but immediately takes posession of the CPU again and you accomplish nothing. Consider `YieldProcessor` or `SwitchToThread` instead. – Andon M. Coleman Aug 16 '16 at 01:03
0

1) if you want to ensure your display is only presented when a vsync occurs, then use D3DPRESENT_INTERVAL_DEFAULT or D3DPRESENT_INTERVAL_ONE.

2) if you want to do some processing while Present() is waiting for the vsync, you can use the D3DPRESENT_DONOTWAIT flag with IDirect3DSwapChain9::Present, this will return D3DERR_WASSTILLDRAWING if the presentation (and vsync) hasn't yet taken place. You can call IDirect3DDevice9::GetSwapChain to get the default swap chain.

3) You can also use IDirect3DDevice9::GetRasterStatus to determine whether the raster (scan line) is in the vertical sync area. This does require driver and hardware support, you can determine whether yours supports it by checking D3DCAPS9.Caps for D3DCAPS_READ_SCANLINE. All modern graphics hardware I know of does expose that cap, but it may also be dependent on the age/type of monitor/TV being used.

Cribbed from: http://www.gamedev.net/topic/319407-wait-for-vsync/

Robinson
  • 9,666
  • 16
  • 71
  • 115
  • Thanks Robinson. I've read the link earlier. However, I'm particularly looking out for a way to use 'WaitForVBlank' in my code. – mots_g Oct 17 '11 at 06:50