Software Support > GroovyMAME
The input lag issue in the context of emulation [about new -frame_delay option]
Dr.Venom:
--- Quote from: Calamity on November 20, 2012, 06:23:39 pm ---So I've been doing some tests these days, and the new option named -frame_delay is going to be ready for the next release. I've done it so that a frame time is divided in 10 parts, so a frame_delay value of 0 (default) means the emulation starts at the beginning of the frame time, as always. A value of 5 means the emulation is postponed to the middle of the frame, and so on (you have 1 tenth of a frame of granularity).
--- End quote ---
That's awesome, I'm looking forward to test driving it.
--- Quote ---I *think* I've done it right and has been working for me, however I need to test it more thoroughly. I have to admit that I can't notice any difference myself.
--- End quote ---
Did you manage to get a "frame missed" counter or logging in? That would be your double check, as pushing the -frame_delay from 0 in steps upwards to 10, should (from a certain value) also see an increased number of frames being missed.
--- Quote ---Second, I've removed the third buffer in -triplebuffer, so now it can be used as an asynchronous implementation of double buffering removing the extra frame in the queue.
--- End quote ---
That's great, it will be exciting to see how the updated version performs. For my understanding, this means it operates with 1 backbuffer and 1 frontbuffer (the one that's drawn to the screen)? And (not wanting to assume too much) how does this exactly differ from the non-asynchronous double buffer?
I was wondering if it would be possible, if time and energy permits, to add the methods of "flip" or "blit" as a separate configurable option to GroovyUME? Not sure how much work it would be, but it might influence the effectiveness of the -frame_delay on different hardware/software configurations and could possibly also be of general benefit when configuring/optimizing GroovyUME with different setups.
--- Quote ---PD: I leave the Win7 vs XP / input latency measurement issues for later posts...
--- End quote ---
That's perfectly fine. First things first...
krick:
Regarding input lag from the hardware perspective...
If you use a keyboard encoder attached to the PC using the PS/2 interface, it is assigned IRQ1 at the hardware level, which is the IRQ with the highest priority. So, in theory, this should have the lowest lag possible on the hardware side. However, I'm not sure what the operating system, driver, etc... do afterwards, lag-wise.
Also, I'm not sure about keyboards, but other inputs like mice are handled in MAME using the RawInput API, which may be different than DirectInput from a lag standpoint.
Check out this info on PS/2 keyboards vs USB keyboards...
http://www.tomshardware.com/reviews/mechanical-switch-keyboard,2955-5.html
Calamity:
--- Quote from: Dr.Venom on November 22, 2012, 04:41:08 am ---Did you manage to get a "frame missed" counter or logging in? That would be your double check, as pushing the -frame_delay from 0 in steps upwards to 10, should (from a certain value) also see an increased number of frames being missed.
--- End quote ---
That would be a bit tricky to implement as it would require accurate time measurements. Anyway I trust my eye more than anything else on this regard.
--- Quote ---For my understanding, this means it operates with 1 backbuffer and 1 frontbuffer (the one that's drawn to the screen)? And (not wanting to assume too much) how does this exactly differ from the non-asynchronous double buffer?
--- End quote ---
Yes that's it. By asynchronous I mean that it can drop frames if required (i.e. the game loop can run as fast as it wants without caring about the video card's duties). This can be achieved either by triple buffering (the real one, not the DirectX crap) or by moving the double buffering code into a separate thread (this is what GM does).
--- Quote ---I was wondering if it would be possible, if time and energy permits, to add the methods of "flip" or "blit" as a separate configurable option to GroovyUME?
--- End quote ---
That would be possible, however you don't have one explicit way of "blitting" in Direct3D AFAIK, the most similar thing seems the D3DSWAPEFFECT_COPY option but I doubt it actually represents an advantage.
Well, there's some interesting stuff I found when testing this -frame_delay method. At first I was using the D3D's default method built in MAME: flip + D3DPRESENT_INTERVAL_ONE, for v-syncing. This method seems the most efficient for catching the vblank period. However there's something odd to it.
I'll try to explain the problem. The -frame_delay option is implemented by moving the throttling wait "loop" after the screen update code, instead of placing it before as it currently is in MAME. Then instead of waiting for a full frame period, we just wait for a fraction of that period, as defined by the -frame_delay option.
One would expect the screen update code to return at exact periods of time forced by the v-sync code, but this is only true for DirectDraw. The Direc3D "present" method seems to take random amounts of time to exit. This is a problem, because it frustrates our efforts to add an accurate wait loop after the update screen code, as it leads to a completely uneven frame rate.
I was about to trash the whole thing but then tried by using the GetRasterStatus method within a loop and right after that performing the flip operation with the D3DPRESENT_INTERVAL_IMMEDIATE flag. Surprinsingly this worked like a charm, but only for CRT monitors!!! For some reason when testing this on LCD monitors the GetRasterStatus seems too slow reporting the VBLANK and you can clearly see static tearing usually on the upper part of the screen. I believe it's always equally slow, it's only that CRT monitors tend to have a longer blanking period so this issue gets masked. But the nice thing is that even if delayed, it flags at exact intervals like a swiss clock, as opposite to the v-synced flipping method.
As a side effect adding this option has resolved a problem I was having for creating a clean implementation of frequency scaling. Unfortunately the flags D3DPRESENT_INTERVAL_TWO, etc, which I expected to use for this do not work under DirectX 9 according to my tests, and I didn't want to resource to the -redraw patch that was plaguing GM with dead locks. Now setting the -frame_delay option to 4-5 works fantastic to force MAME into jumping one out of two vertical retraces, making possible to achieve smooth scrolling for games running at scaled vertical frequencies.
--- Quote ---While doing some first tests with the new frame_delay feature, I also found something interesting that fixes the issue with the <240 line modes running way too fast on my setup (win7+soft15khz), as we spoke about some time ago (see: http://forum.arcadecontrols.com/index.php/topic,120331.msg1313434.html#msg1313434). That speed issue for those specific screenmodes is completely fixed now when I set the frame_delay parameter to 1 (or higher)!
--- End quote ---
My understanding of this is that the DirectDraw's WaitForVerticalBlank method works somewhat differently under Windows 7, so maybe if the emulation is too fast you might end up having a new frame ready *before* the previous vblank actually ended, thus making the new WaitForVerticalBlank call to return immediately. This should be avoided with the DDWAITVB_BLOCKBEGIN flag, but for some reason it might not be working (this could be totally wrong). So adding a delay would give enough time for the VBLANK to end and MAME to catch the next blanking period instead.
krick:
In MAME, some frames take more time to render, depending on what's happening on screen. Doesn't that affect what you guys are trying to do?
Calamity:
--- Quote from: krick on November 27, 2012, 11:55:08 am ---In MAME, some frames take more time to render, depending on what's happening on screen. Doesn't that affect what you guys are trying to do?
--- End quote ---
Definitely, but by placing the wait loop (throttling code) right after the v-synced draw operation, we make sure the difference is absorbed by the wait_for_vblank loop.
So that: emulation_time + wait_for_vblank_time = constant
What we try to achieve is to reduce to the maximum the time the emulator spends waiting for vertical blank, just before the frames that take longer to get emulated start overflowing the time slice provided by the vertical blank. So one needs to explore the right value for -frame_delay, that obviously is game and host system specific.
Navigation
[0] Message Index
[#] Next page
[*] Previous page
Go to full version