Peter Duniho said:
[...]
the code isnt unable to keep up, it can easily manage 500fps with the
test
model im using, the problem is synchronizing it to the frame rate.
The code _is_ unable to keep up. Just because the actual rendering can be
done quickly doesn't change things. The fact that it yields to the OS and
doesn't get scheduled until too late is what prevents it from being able
to keep up. All that "keep up" means is that your code is ready to draw
another frame when the vertical retrace happens.
so its not my code that cant keep up its the underlying API
that cant respond in time. either way its a pointless debate as to where to
aportion blame.
I don't understand that comment. It's not "for some reason". It's for
well-known specific reasons.
then please explain the specific reason using "Present.One" does not presnt
once per frame ie 66fps and instead drops to about 45fps,
wheres as Prsesnt.Imediate manages to display the same thing at 500fps.
so it can hardly be due to running out of processing time.
Your previous message seemed to imply that you understood the issue. This
comment seems to suggest that you don't. Can you clarify?
I understand that it doesnt work very well due to timing problems,
and specificaly why my attempt to use the timer to recitfy this doesnt work
so well,
but I dont understand why a multimedia OS would not have
a smooth mechanism to cope with vsync.
I also think there are more differences between fullscreen and windowed mode
than
I have manged to find out so far.
[...]
Well, sure. If you just busy loop then you're not relying on the thread
scheduler to control the execution of the code. This is in fact how
most
games deal with the issue, and if you want game-like performance, you'll
have to do something similar.
well that shouldnt be the case, the vsync mechanism should be
able to synchronise the frame rate, and it should be able to do so
without having to have a busy loop, or missing frames for no good reason
that I can see. especialy so if as you say the old GDI can do so without
problems.
If all you do is wait on the vertical retrace, it will work fine. And I
thought that's exactly what you wrote in your previous message.
its not fine if it uses 100% cpu. to do 5% real work.
But the vertical retrace synchronization isn't the only thing you need to
worry about. As soon as you bring other aspects of the OS into the
picture, such as the thread scheduler, your code is at risk for not being
able to keep up.
[...]
I dont think this is a real-time issue at all,
It is.
arguing about the definition of wether an issue is real time
is often a long and pointless debate. this is however a multimedia issue
and this is described as a multimedia capable OS.
It's not just an issue of "timer granularity". It's that once you yield
your thread to Windows, lots of other threads get a chance to run
(including some other ones in your process). You have no control over
when your thread will get control back.
again this isnt an issue because the background work is miniscule.
there is plenty of spare time to go nearly 10 times as fast as needed.
if theres work to be done elsewhere then the graphics isnt a priority so
its not big issue. but its a waste if its doing nothing else and still cant
manage it.
the point is to at least get it working well when its got lots of spare
procesing.
High frame rates and low CPU utilization are mutually exclusive. This is
true even on a real-time OS.
I dont need high frame rate as such I need to synchronize to vsync.
66fps is about 5% cpu, what I dont need is 66fps with 100% cpu 95% of wich
is wasted.
For what it's worth, DirectX has (or at least, did ten years ago...it
should still be in there somewhere) a way to use double-buffering and tell
the driver to flip to your newly rendered frame when _it_ can, rather than
your own code waiting for the vertical retrace. Using this technique, you
should be able to draw into an on-screen video surface at any time, with
the "flip" (oftentimes this is actually just a blt, especially if you're
not doing full-screen video) happening during the vertical retrace under
control of the video driver.
Unfortunately, it's been a long time since I've messed around in that API
so I can't provide the specifics. And of course, depending on how you're
accessing DirectX via .NET, that part of the API may or not actually be
exposed. But I do remember that it was part of DirectDraw, and inasmuch
as any of DirectDraw is still around (I seem to recall it getting
superceded by Direct3D somehow, or merged with, or whatever), it's
probably still there.
well I was pretty sure you should be able to do something like that quite
easily.
im not sure if using multiple swap chains or something else im doing is
cuasing problems,
again I think this might actualy work more smoothly in fullscreen mode .
but I have tried al maner and permutations of options such as the folowing
:-
seting the SwapEffect from SwapEffect.discard,copy,flip.
setting present interval to imediate,one,defualt,
seting the number of backbufers from 1 to 3,
using DoNotWait parameter on the SwapChain.Present
and also setting the ati control panel options for vsync
from 1=never to 4=always
and it either goes at 500fps or 45fps never 66fps !
im sure it isnt this hard im surprised there isnt an easy answer,
however I have come accros this and managed to get something similar to
work.
http://www.codeproject.com/KB/GDI/tearingfreedrawing.aspx
it looks at the current scan line then sets up a multimedia timer
to fire when it predicts the vertical refresh to ocur.
seems to work reasonably well, however its not ideal as it is a prediction
for vsync wich isnt able to know the time its going to take to render the
frame in advance.
unfortunatly this is also true of sitting in a busy loop.
im not sure if its posible to do the rendering then wait for vsync then do
present as
it seems to just queue up al the draw operations then execute them once
present is called.
Colin =^.^=