   Best way to do "sync to every SECOND vsync."
  I'm going to present my application on an LCD screen having a refresh of 75 Hz.Currently the application doesn't run 75 fps+, it's somewhere around the 50-100 fps region.I.e I get frame times like this: 13.3 ms, 26.6 ms, 26.6, 13.3, 26.6, 26.6 and so on.The application is VERY sensitive to getting smooth frame rates, thus I need to lock it to the V-sync.The graphics adpater that I use doesn't support D3DPRESENT_INTERVAL_TWO.How would you go about to sync the application so that it only presents every second frame (i.e 37.5 fps)?The CPU usage is always below 13 ms, so the frame rate is always based on the GPU performance.If I could somehow detect that the GPU used less than 13 ms when rendering a frame I could stall the application for 8 ms or so, can you do that?Any hints are welcomed!Edit: On console this is easily achieved, almost all consoles I've worked on had a v-sync interrupt so you'd just put a frame counter in there and waited until the right number popped up before presenting the screen. Is there some way to do this under DirectX / Win32?[Edited by - eq on January 6, 2006 7:05:56 AM]
  hmm, timing issues - always great fun [oh]Firstly, I would avoid against using a Sleep() call to try and stall - it might work, but last time I checked it's defined to sleep for at least but not exactly the time you specify. Also, for units such as 8ms you could hit timer resolution/accuracy issues.You could possibly use a high-res timer and do a busy-waiting stall... but that's not exactly good practice nor efficient use of resources [wink]I'm sure a WaitForVSync() or similar flag/method existed in either and older D3D or DDraw, but I can't find any reference to it, but it looks like IDirect3DDevice9::GetRasterStatus() might be useful - monitoring it might be difficult though.One other thing - does it have to be a multiple of the refresh rate? or would it work if you just clamped it at something so long as it was a constant something?Failing those, maybe you could try and use the OS and/or device-driver interfaces to try and query the current refresh rate.hthJack   ;Quote:Firstly, I would avoid against using a Sleep() call to try and stall Yes, I know that, Sleep is very unreliable IMO.Quote:You could possibly use a high-res timer and do a busy-waiting stall... but that's not exactly good practice nor efficient use of resourcesI'm not to concerned about eating up all available CPU cycles since this is an application that will run on a dedicated hardware (specified by me). The problem is to find out WHEN to wait.If I wait a constant X ms every frame I'm afraid that for certain frames I'd be stalling to much (I do have some spikes in the CPU usage when I need to process some additional networks packets etc).I could ofcourse try to monitor the CPU usage and try to always wait 25 ms or so... I'll try that.Quote:IDirect3DDevice9::GetRasterStatus() might be useful - monitoring it might be difficult though.That's also a method to check out, I guess I could do the monitoring in a separate thread and if NewRaster < OldRaster count up a frame counter.Quote:One other thing - does it have to be a multiple of the refresh rate? or would it work if you just clamped it at something so long as it was a constant something?I think it have to be locked to the refresh rate, I could be wrong however, haven't tried to lock it to a "constant something".Thanks, I guess I have some options to play around with.. now if I only had the time... ;)   ;  From the documentation of IDirect3DDevice9::GetRasterStatus():Quote:This method will not return device state for a device that is created using D3DCREATE_PUREDEVICETo bad, I dunno how my application performs without a pure device.;Quote:Original post by eqFrom the documentation of IDirect3DDevice9::GetRasterStatus():Quote:This method will not return device state for a device that is created using D3DCREATE_PUREDEVICETo bad, I dunno how my application performs without a pure device.I've often found the difference to be negligable if anything.It's been a while since I tried it, but PD's were included so that the drivers/hardware had some added "room to manouever" when it came to state management - it can be quite efficient to avoid any Get**() calls.Going from a PD to non-PD is a trivial change of flag - won't hurt to try it. It's going from non-PD to PD that can be a bit tricky [smile]hthJack   