The Big BlitzMax Lag Test

BlitzMax Forums/BlitzMax Programming/The Big BlitzMax Lag Test

Grey Alien(Posted 2011) [#1]
OK folks, I've written some test code to demonstrate the BlitzMax DX9/OpenGL rendering lag and proposed fix by CyBeRGoth.

Summary: DX9 and OpenGL have unacceptable rendering lag in full-screen mode, but it can be fixed. Windowed mode needs more work to fix.

[EDIT] There seem to be a few misunderstandings about the issue, so please let me clarify:

1) This is a RENDERING lag, not just a mouse lag, so if you use keys to control a character, you'll see the same lag. Therefore doing fancy stuff with the mouse cursor is not a solution.

2) There's no point in discussing timing solutions (and the lack of timing other than vsync in the test code below) as there will still be a rendering lag no matter what timing solution is used if VSync is also on.

3) I don't want a solution that involves turning off VSync because I don't want to have vertical tearing in my game. There was no lag in DX7 with VSync - I would just like the same for DX9/OpenGL.
[/EDIT]

Please test it on your machines and report your findings. Here's what I see:

Full Screen Mode (fix off):
- DX7 green square is smooth, blue square lags a little bit.
- DX9 green square is smooth, blue square lags a A LOT.
- OpenGL green square is smooth, blue square lags a almost as much as DX9.

Full Screen Mode (fix on):
- DX7 green square is smooth, blue square lags a little bit (same as before)
- DX9 green square is smooth, blue square lags a little bit (same as Dx7)
- OpenGL green square is smooth, blue square lags a little bit (same as Dx7)

Full Screen conclusion: There's a bad lag in DX9 and OpenGL but the fix works and doesn't have an adverse effect. I didn't expect a lag in OpenGL, so that's a surprise.

Windowed Mode (fix off):
- DX7 green square is a bit jerky, blue square lags a little bit.
- DX9 green square is smooth, blue square lags a more than DX7.
- OpenGL green square is smooth, blue square lags about the same as DX9.

Windowed Mode (fix on):
- DX7 green square is smooth, blue square lags a little bit (same as before)
- DX9 green square is smooth, blue square lags more than DX7 (ame as before)
- OpenGL green square is smooth, blue square lags about the same as DX9 (same as before).

Full Screen conclusion: DX7 Flip is jerky but is still VSynced. There's a medium lag in DX9 and OpenGL. The fix has no effect (bad or good) to any driver.


***GRAND CONCLUSION***

If you want your DX9 and OpenGL full-screen games to feel responsive, you need to use the fix. Also we *need* a fix for windowed mode too, and that's where I'm hoping the uber-intelligent members of the community can help out! Thanks in advance for your help, this benefits us all.

Also can anyone foresee any possible adverse effects from using the fix below?

**********************

[EDIT]I now made the code Mac compatible. On Mac I see almost no lag at all in FullScreen mode and the fix does nothing. In windowed mode I see a small lag and I'm not sure if the fix does anything, it feels like maybe it does, but it's hard to say. What do you see?
[/EDIT]

SuperStrict

Const DIRECTX7% = 0
Const DIRECTX9% = 1
Const OPENGL% = 2

Global currentDriver% = DIRECTX7
?MacOS
currentDriver = OPENGL
?
Global fullScreen% = 1
Global useFix% = 0
Global screenWidth% = 0
Global screenHeight% = 0
Global blockX% = 0

SetDriver()
CreateScreen()

While Not KeyHit(KEY_ESCAPE)
	Test()
Wend

End

Function Test()
	Cls

	SetColor 255,255,255
	Local x%,y% = 10
	Local gap% = 15
	DrawText "Press D to change Driver (current = "+GetDriverString()+")",x,y
	y:+gap
	DrawText "Press F to toggle Fix (current = "+useFix+")",x,y	
	y:+gap
	DrawText "Press S to toggle Full Screen",x,y	
	y:+gap
	DrawText "Press Esc to Exit",x,y	
	
	SetColor 100,100,230
	DrawRect MouseX(),MouseY(),50,50
	
	SetColor 100,230,100
	DrawRect blockX, screenHeight-100,50,50
	blockX:+1
	If BlockX>screenWidth Then blockX:-screenWidth
	
	If useFix Then
		Local MouseHack:TPixmap
		MouseHack = GrabPixmap(1, 1, 1, 1)
	EndIf
	
	Flip 1
	Delay(1)	
	
	?win32
	If KeyHit(KEY_D) Then
		currentDriver:+1
		If currentDriver>OPENGL Then currentDriver= DIRECTX7 'wrap
		SetDriver()
		CreateScreen()
	EndIf
	?
	
	If KeyHit(KEY_S) Then
		fullScreen = Not fullScreen
		CreateScreen()
	EndIf

	If KeyHit(KEY_F) Then
		useFix= Not useFix
	EndIf

End Function

Function SetDriver()
	Select currentDriver
		?win32
		Case DIRECTX7
			SetGraphicsDriver D3D7Max2DDriver()
		Case DIRECTX9
			SetGraphicsDriver D3D9Max2DDriver()
		?
		Case OPENGL
			SetGraphicsDriver GLMax2DDriver()
	End Select
End Function

Function CreateScreen()
	If fullScreen Then
		screenWidth = 800
		screenHeight = 600
		Graphics screenWidth, screenHeight, 32
	Else
		screenWidth = 640
		screenHeight = 480
		Graphics screenWidth, screenHeight, 0
	EndIf	
End Function

Function GetDriverString$()
	Select currentDriver
		Case DIRECTX7
			Return "DirectX 7"
		Case DIRECTX9
			Return "DirectX 9"
		Case OPENGL
			Return "Open GL"
	End Select
End Function


Last edited 2011

Last edited 2011


therevills(Posted 2011) [#2]
DX7 Window: Slight lag
DX7 Window with Fix: Slight lag
DX7 Full Screen: Slight lag
DX7 Full Screen with Fix: Slight lag

DX9 Window: Noticable lag
DX9 Window with Fix: Noticable lag (no change)
DX9 Full Screen: Noticable lag
DX9 Full Screen: Slight lag

OpenGL Window: Noticable lag (same as DX9)
OpenGL Window with Fix: Noticable lag (no change)
OpenGL Full Screen: Noticable lag
OpenGL Full Screen: Slight lag

OpenGL and DX9 performed very similar to each other...


Grey Alien(Posted 2011) [#3]
Great thanks for testing. Your results are the same as mine then.


joncom2000(Posted 2011) [#4]
DX7 Window: Slight lag
DX7 Window with Fix: Slight lag
DX7 Full Screen: Slight lag
DX7 Full Screen with Fix: Slight lag

DX9 Window: Slight lag
DX9 Window with Fix: Slight lag
DX9 Full Screen: Noticable lag
DX9 Full Screen: Slight lag

OpenGL Window: Noticable lag
OpenGL Window with Fix: Noticable lag
OpenGL Full Screen: Slight lag
OpenGL Full Screen: Slight lag

Athlon Quad Core, Vista 32bit, ATI HD4830

Hmm seems I dont lag in a window in dx9 any different to dx 7 and opengl fullscreen seems pretty low on lag but more moticable windowed.


*(Posted 2011) [#5]
same as joncom2000 here:
WinXP, Intel 945, 1Ghz Atom

Last edited 2011


ziggy(Posted 2011) [#6]
Just in case... couldn't you just use Flip -1 and use delta timing? This should avoid the issue... ? Obviously Graphics has to be created without vertical sync, I mean, Graphics width, height, colordepth, 0
most computers don't use CRC monitors nowadays, so I see no problem on doing it this way.

I got a version of your sample that is lag free, but it's using a custom built delta-timing module.

Here's the delta module source:

file: deltatiming.bmx


And this is the "fixed" sample:
SuperStrict
Import "deltatiming.bmx"

Const DIRECTX7% = 0
Const DIRECTX9% = 1
Const OPENGL% = 2

Global currentDriver% = DIRECTX7
Global fullScreen% = 1
Global useFix% = 0
Global screenWidth% = 0
Global screenHeight% = 0
Global blockX:Float = 0

SetDriver()
CreateScreen()

While Not KeyHit(KEY_ESCAPE)
	Test()
Wend

End

Function Test()
	Cls

	SetColor 255,255,255
	Local x%,y% = 10
	Local gap% = 15
	DrawText "Press D to change Driver (current = "+GetDriverString()+")",x,y
	y:+gap
	DrawText "Press F to toggle Fix (current = "+useFix+")",x,y	
	y:+gap
	DrawText "Press S to toggle Full Screen",x,y	
	y:+gap
	DrawText "Press Esc to Exit",x,y	
	
	SetColor 100,100,230
	DrawRect MouseX(),MouseY(),50,50
	
	SetColor 100,230,100
	DrawRect blockX, screenHeight-100,50,50
	blockX:+1 * Delta.Factor()
	If BlockX>screenWidth Then blockX:-screenWidth
	
	If useFix Then GrabPixmap(1, 1, 1, 1)
	
	Flip(-1)
	Delay(1)
	
	If KeyHit(KEY_D) Then
		currentDriver:+1
		If currentDriver>OPENGL Then currentDriver= DIRECTX7 'wrap
		SetDriver()
		CreateScreen()
	EndIf

	If KeyHit(KEY_S) Then
		fullScreen = Not fullScreen
		CreateScreen()
	EndIf

	If KeyHit(KEY_F) Then
		useFix= Not useFix
	EndIf

End Function

Function SetDriver()
	Select currentDriver
		Case DIRECTX7
			SetGraphicsDriver D3D7Max2DDriver()
		Case DIRECTX9
			SetGraphicsDriver D3D9Max2DDriver()
		Case OPENGL
			SetGraphicsDriver GLMax2DDriver()
	End Select
End Function

Function CreateScreen()
	If fullScreen Then
		screenWidth = 800
		screenHeight = 600
		Graphics screenWidth, screenHeight, 32, 0
	Else
		screenWidth = 640
		screenHeight = 480
		Graphics screenWidth, screenHeight, 0, 0
	EndIf
End Function

Function GetDriverString$()
	Select currentDriver
		Case DIRECTX7
			Return "DirectX 7"
		Case DIRECTX9
			Return "DirectX 9"
		Case OPENGL
			Return "Open GL"
	End Select
End Function


Last edited 2011

Last edited 2011

Last edited 2011


GfK(Posted 2011) [#7]
I get slight lag in all cases, with the 'fix' making no difference whatsoever. And from what I've seen I'm still unconvinced this is a big problem. Sure, some people claim huge/small/low/lots of lag but what does that really mean? Its all subjective, really.

One observation I made from the code above, is that you have Flip 1 in there, and then on the very next line you have Delay 1. This is going to exaggerate any lag effect as you're telling the driver to wait for a vertical blank before flipping, then waste another tick doing absolutely nothing. If you take out the Delay you'll see in task manager that CPU usage is virtually zero anyway. Only a small demo, granted, but my current game is exactly the same and I'm not using a Delay.

On the whole, the system mouse pointer is governed by the OS and is completely independent of your app. When you use a custom mouse pointer, then all you're really doing is drawing an image at the coordinates the mouse *was* at when you did the drawing. By the time you get to the next Flip then that's always going to be a few millisecs ago, hence the so-called lag.

I'm not concerned at all about this any more.


SLotman(Posted 2011) [#8]
Just a small comment: I never updated my bmax from 1.28 - and I still use DStatny's DX9 module... which has NO LAG on DX9 in that sample.

I do get a small lag on DX7 fullscreen, and a big one in OpenGL fullscreen. (and the same in windowed mode).

The fix only helped OpenGL windowed mode.

Now try THIS for a change:



No 'mouse fix' necessary. Just Flip 0, and a small code to wait for 60 fps.
With this, I get no mouse lag, on any driver.

The post above which says about Flip 1 : Delay 1, is completely correct btw - you're waiting for the vertical retrace to end, and on top of that waiting 1 more millisecond, which seems to be the cause of the lag.

On my code above - I render the screen as fast as possible - then I wait 'manually' for 60fps, with delay to release the extra time to the OS.

I believe bmax has this built-in with Flip -1, but haven't tested it.

Last edited 2011

Last edited 2011


GfK(Posted 2011) [#9]
I don't think that using a software version that's three years out of date, is any solution at all. There will be countless other issues that have been fixed in more recent versions.

You could probably use Doug's DX9 module with the latest version of Blitzmax if you wanted to.


SLotman(Posted 2011) [#10]
Yeah, but I've been fixing stuff myself, I made all modules superstrict, built some custom commands like AppIcon, etc. So it isn't exactly 'vanilla bmax 1.28' :)

The solution isn't on bmax 1.28 - read my post again, and you'll see it's probably the flip 1 / delay 1 thingie.

Last edited 2011


maverick69(Posted 2011) [#11]
Can somebody explain to me how and why the fix works:

Local MouseHack:TPixmap
MouseHack = GrabPixmap(1, 1, 1, 1)


Sorry, if this was discussed earlier, but I didn't found anything related on the forum.


HrdNutz(Posted 2011) [#12]
It seems the problem if Flip related; with vsync enabled the driver waits before presenting the back buffer, so when you see the frame, it was actually from long time in the past, and the system mouse has plenty of time to do some roaming around the screen.

Disabling vsync allows faster screen presentation, thus reducing the discrepancy between code and system pointers. That's why SLotman's example works; you present the frame first and the timing delay happens while you are already looking at the current frame, instead of waiting to see it.

Syncing up the pointers with vsync enabled appears to be problematic or impossible. Disabling vsync breaks smoothness for some games. It's really a trade-off.

Something like this could work in theory, but does not in reality:

cls
drawgame()
flip 1
drawmouse()
flip 0

Using FlipHook doesn't work either, because the delay is in the driver, so that makes no difference.


DStastny(Posted 2011) [#13]
The fix works by stalling the GPU. Grabbing a pixmap requires the GPU to finish drawing before the lock in in place.

On my version of the DX Driver I implemented a CompletionQuery to determine when the GPU was finished drawing as opposed to locking. It seemed to work correctly on windows mode where locking did not.

I pretty much abandoned working on the DX9 driver since most people thought mark would do better job with "Official" one. Code is still on Google if anyone wants to try and retrofit the code into Mark's driver.

Doug


Grey Alien(Posted 2011) [#14]
Thanks for testing and for everyone's suggestions:

Some points:

1) I don't want to use Flip 0 or -1 as it will result in tearing on the graphics, this is why I have used VSync for years.
2) They Delay(1) is not causing a problem. Take it out and see for yourself.
3) It's not just an issue with the mouse. If you code in a block that moves with the keys, you'll see the same lag issue.

My understanding of the problem is the same as HrdNutz in that the display gets more than one frame behind. Back in 2006/07 the same issue existed with DX7 and we used a temporary fix (which started off as a GrabImage I believe and then got more sophisticated) for a while until BRL fixed it. Now I believe the same needs to happen for DX9.

@DStastny: So your fix works in windowed mode, sounds good! Any chance of posting that code here for lazy folks like me and suggesting where it needs to be used? Thanks!


Grey Alien(Posted 2011) [#15]
Ok I just made the test Mac compatible and I found this:

On Mac I see almost no lag at all in FullScreen mode and the fix does nothing. In windowed mode I see a small lag and I'm not sure if the fix does anything, it feels like maybe it does, but it's hard to say. What do you see?


SLotman(Posted 2011) [#16]
Flip 0 won't cause tearing by itself.

Tearing happens only if you redraw the screen again, before the screen drawing (the vertical retrace) is completed - so you get part of the old screen and part of the 'new' one visible at the same time.

The waiting code right after the flip prevents it - unless the computer is too slow to draw the whole screen - which then you should use flip false anyway to improve performance.


Grey Alien(Posted 2011) [#17]
SLotman: Your code exhibits vertical tearing quite clearly in full screen mode and jerkiness in windowed mode on my PC (make the box about 500 pixels and it's really obvious). The timing code you've added isn't accurate enough because 60Hz means 16.6666666 (recurring) millisecs per frame (so it'll go out of sync every so often). Also you are starting the timer at an arbitrary place in the draw cycle. The only way flip 0 would not show tearing is if you called it when the scan line was at the top or bottom of the screen, which effectively means it is vsynced anyway.

Last edited 2011


H&K(Posted 2011) [#18]
Ermm,

I don't see how anyone can say that they had lag on the green box, because there is nothing to compare it with (Ie the blue box is lagging compared to the mouse, but the green is just incomparable)

Having said that, the green box in my opengl example moves about 40 times faster then the dx ones.

As to the mouse,

You know those games that are normally full screen, but for some reason they drop to windowed? (like when your firewall pops up or the like). Well anyway often you have two mice pointers at that point, the OS one, and the game one.
I cannot think of a single example where this happens that the game one DOESN'T lag the OS one.


Grey Alien(Posted 2011) [#19]
@H&K: No one is saying they had lag on the green box, that's just there to test how smooth the vsync is.

Sounds like you've disable vsync for OpenGL for your videocard, which is why you can't rely on vsync for timing, and need delta time or fixed rate logic.

Yes the game pointer will always lag the OS one, but the idea is to reduce that lag as much as possible, and it's much worse in some drivers than others.


H&K(Posted 2011) [#20]
@H&K: No one is saying they had lag on the green box, that's just there to test how smooth the vsync is
doh

OK, new test, can everyone add the command
Hidemouse()

Just after CreateScreen().

Ok, who still has a noticeably lagging blue box?

I know this "isn't" a fix, but on my system at least I'm totally unable to tell that the box is lagging my mouse movements. I'm gonna ignore this problem unless someone is able to tell (easily) that lag is there without the OS mouse visible

Edit. If it gets "fixed" thou I wouldn't ignore the solution

Last edited 2011


ziggy(Posted 2011) [#21]
I think the lag is caused directly becouse of the system.Poll being called before the flip operation, and the Flip operation taking too long, so when the drawed rectangle is finally shown, it is "late" it has wrong coords. It seems that the DX7 is making the SystemPoll with some diferences, so the data is not calcualted until it is requested on code, or the wait operation happens after the frame is shown (then wait, and then refresh poll). IMHO This should be the best scenario, but haven't tested.

EDIT: This is just an assumption, haven't found a way to reset the PolledInput after each Flip operation to see if it makes any difference...

Last edited 2011


Grey Alien(Posted 2011) [#22]
Ok, who still has a noticeably lagging blue box?
I do and my customers noticed it too, which I why I brought up the whole issue. The mouse cursor is just shown here to help clearly identify and fix the problem. You can ignore the problem, but I don't want to because I view it as serious, especially for arcade games where you use keys to control a character (which I started to make recently) - it feels really laggy and will result in lost sales and bad reviews.

@Ziggy: This is the old code that fixed the issue on DX7, you can see it locks,unlocks the buffer which is like using the GrabImage fix from above:


		If TD3D7Max2DDriver(_max2dDriver)
			Local sdesc:DDSurfaceDesc2 = New DDSurfaceDesc2
			sdesc.dwSize = SizeOf(sdesc)
			Local res:Int = PrimaryDevice.backbuffer.Lock(Null,sdesc,DDLOCK_WAIT|DDLOCK_READONLY,Null)
			PrimaryDevice.backbuffer.unlock(Null)
			Return res
		EndIf



H&K(Posted 2011) [#23]
Change
DrawRect MouseX(),MouseY(),50,50

to
DrawRect MouseX()+MouseXSpeed(),MouseY()+MouseYSpeed(),50,50



Grey Alien(Posted 2011) [#24]
An interesting workaround thanks. That appears to make the lag look less bad, but it feels odd - hard to describe, but like jerky or something. Unfortunately I can't use the same technique for keyboard input.


H&K(Posted 2011) [#25]
That appears to make the lag look less bad, but it feels odd - hard to describe, but like jerky or something
Thats because the OS is probably using some sort of mouse smoothing, whereas the blue box isn't. (This means the Blue Box is REALLY where the mouse is pointing, and its the mouse which is all "damp and stiff)

It's quite easily fixed by putting in some mouse smoothing ie
DrawRect MouseX()+(MouseXSpeed()+lastmousexsp)/2,MouseY()+(MouseYSpeed()+lastmouseysp)/2,50,50
However it will now almost certainly NOT keep pace with the OS mouse on the start of fast movements, (which I think you will attribute to lag, rather than simply different positional results)
DrawRect MouseX()+(MouseXSpeed()+lastmousexsp/2)/1.5,MouseY()+(MouseYSpeed()+lastmouseysp/2)/1.5,50,50
Gives a better result, but again it wont look exactly like the OS, because as you said its just a workaround and without knowing exactly how the OS is going to calculate it, we are just theory modelling

As to the key input, no idea sorry, Im in the Fixed timed Event driven camp, and as long as Im keep ontop of the queue dont seem to have any problems. PLUS cos I dont have clients/customers I can accept things like this if they dont bother me that much.
(PS If no one else is Fixed Timed Event Driven, then Im obviously just a camp of one ;(

Last edited 2011


maverick69(Posted 2011) [#26]
Isn't it possible to use the OS "Hardware"-Cursor?

Mac OS X:
https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/ApplicationKit/Classes/NSCursor_Class/Reference/Reference.html

Windows:
http://msdn.microsoft.com/en-us/library/ff468815(v=VS.85).aspx

I tried it on OS X and it seems to work in windowed mode. If I switch to fullscreen within the BlitzMax Application it also works, but if I start in Fullscreen Mode it doesn't work. Very weird.

Didn't tried it on Windows yet.

I think there are also some restrictions in image size and depth of the cursor image.

because the delay is in the driver


Hmmm... so can't it be fixed within the max2d-driver instead of writing ugly workarounds (or did you mean the problem is in the OS Driver)???


col(Posted 2011) [#27]
@Grey Alien...

Hiya,
Is this the same method that you use in all your games ??

I'd recommend to use delta timing for all games, specifically so that all machines can visualise your games at the same speed ( the speed that the game is intended to be viewed at ).
You'd get a uniform gameplay speed across all machines regardless of the cpu and gpu speeds.
Your code does show the lag, but its too dependent on 'waiting' for the VSync.
Ziggys code is a good example of how to incorporate it and it doesnt suffer any lag at all in fullscreen and only the tiniest lag ( which is so small i shouldn't really even mention it, but it is there ) in windowed mode for all drivers.

Last edited 2011


Grey Alien(Posted 2011) [#28]
Thanks for the cursor suggestions people, but it's not just a mouse issue, it's a display lag and so keyboard input also lags. Doing stuff with the mouse only solves half the problem.

@Jochen: I'm pretty sure the BlitzMax DX9/OpenGL drivers just need some small tweaks by BRL, like they did for DX7 a few years back to remove its display lag.

@col: No, of course I don't use that timing for my games :-) I have a good timing method in my framework, this is just a quick bit of sample code to show the lag issue (as per your request). Ziggy's code is fine if you want a game with no vsync that will display vertical tearing, but I prefer to use vsync. With Flip 1 in Dx7 there's only a tiny lag that no one really notices, so the problem is definitely with the Blitzmax DX9 (and OpenGL) drivers - that's what I'm trying to get a fix for. The most promising of which seems to be Doug's, so I hope he checks back in soon...


maverick69(Posted 2011) [#29]
@col

delta timing has other problems, for example if the framerate drops it's possible, for example, that collisions don't work any more. also, if most of the game works with integers some floating accuracy problems may occur.

another possibility is to use render tweening which is the best way to go, but it requires some extra work and is hard to implement if you have an almost finished projects.


Grey Alien(Posted 2011) [#30]
Did some research and someone else (http://www.gamedev.net/topic/457105-mouse-lag-under-directx9/) said "The thing causing the lag was the presentation interval. I've switched from INTERVAL_IMEMDIATE to INTERVAL_ONE, and no problems!"

Also a good explanation here of why there's a 50ms lag and using a similar lock/unlock fix: http://area.xors3d.com/forums/viewtopic.php?f=7&t=470&start=0

Some people trying to solve the problem in Ogre: http://area.xors3d.com/forums/viewtopic.php?f=7&t=470&start=0

There's a really good detailed post by Zoner at the bottom of this thread: http://www.gamedev.net/topic/592845-vsync-causing-input-lag/


Grey Alien(Posted 2011) [#31]
And also a similar explanation from NVidia http://www.nvidia.co.in/object/General_FAQ.html#G4


Grey Alien(Posted 2011) [#32]
This seems to be the thread in which Doug says he fixed render buffering (input lag) but I can't see where to download the driver from, it's getting late here so I may just be blind: http://www.blitzbasic.com/Community/posts.php?topic=84089


col(Posted 2011) [#33]
@maverick69

Thats very true. If youre going to use it then you need to build everything from the start incorporating it.
Not a good idea if the project is finished or near completion.

@Grey Alien
Is This what you're looking for ?? I haven't checked it yet.

Last edited 2011


Grey Alien(Posted 2011) [#34]
Looks like it thanks col. I still don't know if I'll be able to find the magic code and then figure out where to put it in BRL's DX9 modules. That's the bit I'd love some help with.


col(Posted 2011) [#35]
Out of curiosity, are those suffering from the lag using LCD or CRT screens ? If people wouldnt mind replying with 'Yes/No to lag, LCD or CRT'. Thanks.

@Grey Alien...
That code doesn't work 'as is' when simply put into the mod folder and built. It needs a few tweeks, maybe because of BMax updates? Also the code looks very similar in logic to the DX7 driver code... hmm :o)

Stay tuned... this isnt dismissed.

Last edited 2011


Grey Alien(Posted 2011) [#36]
OK cool. Glad someone with epic skillz is on the case!

I was using LCD, but seeing as you can see the system mouse and the blue square are clearly lagging, screen type shouldn't make a difference right? If there was no system cursor, then sure the lag could potentially be blamed on display device (like laggy large screen TVs and the Rock Band calibration you have to do).


TaskMaster(Posted 2011) [#37]
This result is because of vsync. I don't think you will be able to fix it.

What you are seeing is that you prepare your screen to be drawn, but then wait for 15ms before you draw it. The world hasn't stopped to wait, the mouse is still moving. So, when your screen finally draws to screen, the user has moved the mouse for 15ms more.

I do not believe there is any way you are going to fix this. The only way to truly minimize this effect is to somehow know when the flip is going to occur, and draw your screen 2ms before the screen updates.

In other words:

With a vsync of 60, each frame is drawn every 16ms. This is an example of how it is progressing...

1ms: you get the mouse coords and draw all of your stuff.
2ms: you sit and wait for the vsync
3ms: you sit and wait for the vsync
.
.
.
15ms: you sit and wait for the vsync
16ms: you display your screen

You updated the positions of everything and read the keyboard inputs and whatnot 15ms ago, but you just now displayed your screen. But, the mouse has continued to be moved for 15ms more in between that time.

Now, if you could somehow do this:

1ms: Do nothing
2ms: Do nothing
3ms: Do nothing
.
.
.
15ms: Get the mouse coords and draw all of your stuff
16ms: Display your screen

then apparent the lag would go away. I do not think it has anything to do with the drivers or anything else. It is just the way you are doing it. There is no simple solution except trying to guess when the vsync will happen and not updating your screen until right before.


TaskMaster(Posted 2011) [#38]
And, I believe the reason you think you see more lag in DX9 is because DX9 is faster than DX7. DX7 is taking a bit longer to do the graphics operations so there is maybe 11ms of dead space between between your logic and the screen actually displaying. Whereas DX9 is probably so much faster that there is 14 or 15ms of dead space between your logic and the screen actually updating.

If you could somehow figure out how much dead time there is, then you could delay that much before doing your logic, then your logic would be happening right before the screen displays and your logic would not lag a tiny bit.

That is why not using vsync and delta timing seems to solve the problem.


col(Posted 2011) [#39]
Can you try this code. I've incorporated the basics from the driver by DStastny into my core BMax setup. Had to change a few things including some filenames to get it working with minimal changes. There is still some work to be done in the driver but let's see if it a viable fix first before proceeding any further.

NOTE :- Its only the DX9 driver code that has changed. It uses the test code from the very first post above without any alterations at all. To be honest its seems to be the best ( most minimal lag while not using some kind of delta timing ) on my system in fullscreen and windowed mode, and using the fix option actually creates a slight lag in all modes by comparison.

One side effect is that the blue box isnt as smooth as with the original driver code, but it keeps up with the mouse, only lagging a few pixels at most, a small price to pay??

DOWNLOAD HERE

Last edited 2011


Grey Alien(Posted 2011) [#40]
@TaskMaster: The lag is much longer than a few milliseconds, it's several frames. Those links I posted explain what DX9 is doing that makes the lag worse. I agree that within a single frame, yes it would be better to read the mouse position at the end if using VSync.

@col: Awesome, testing now.


Grey Alien(Posted 2011) [#41]
@col: Great work! Here are my findings:

Windowed Mode DX9: The lag does seem to be reduced a bit so it's less than OpenGL, but it's still not as minimal as DX7. One problem is that the green square is jerky now, which must mean that the graphics card isn't delivering the frames smoothly. If I switch on the original fix the green square becomes a lot smoother and so does the mouse movement.

Full Screen Mode DX8: The lag is tiny (better than DX7), it's truly excellent. However, again the green square is jerky, and if I turn on the fix it becomes smooth.

So perhaps some combination of both fixes (original + yours) is required?


HrdNutz(Posted 2011) [#42]
TaskMaster is right, the lag is coming from one frame because the driver waits to present the screen with vsync enabled. Delaying the Flip call and processing input right before can help reduce the discrepancy, but you gotta be careful and not delay long enough to miss the vertical trace.

I modified the original code to demonstrate:

moved the mouse and input code after the delay
added quick check for delta time
removed the delay after Flip (not sure why its there to begin with)

SuperStrict

Const DIRECTX7% = 0
Const DIRECTX9% = 1
Const OPENGL% = 2

Global currentDriver% = DIRECTX9
?MacOS
currentDriver = OPENGL
?
Global fullScreen% = 1
Global useFix% = 0
Global screenWidth% = 0
Global screenHeight% = 0
Global blockX% = 0

SetDriver()
CreateScreen()

While Not KeyHit(KEY_ESCAPE)
	Test()
Wend

End

Function Test()
	Local frame_time# = MilliSecs()
	Cls

	SetColor 255,255,255
	Local x%,y% = 10
	Local gap% = 15
	DrawText "Press D to change Driver (current = "+GetDriverString()+")",x,y
	y:+gap
	DrawText "Press F to toggle Fix (current = "+useFix+")",x,y	
	y:+gap
	DrawText "Press S to toggle Full Screen",x,y	
	y:+gap
	DrawText "Press Esc to Exit",x,y	
	
	SetColor 100,230,100
	DrawRect blockX, screenHeight-100,50,50
	blockX:+1
	If BlockX>screenWidth Then blockX:-screenWidth
	
	If useFix Then
		Local MouseHack:TPixmap
		MouseHack = GrabPixmap(1, 1, 1, 1)
	EndIf
	
	' process input and mouse after this delay
	' you want to stall as long as possible,
	' but not long enough to miss the vertical trace
	frame_time = MilliSecs() - frame_time
	Delay(16 - frame_time)	
	
	?win32
	If KeyHit(KEY_D) Then
		currentDriver:+1
		If currentDriver>OPENGL Then currentDriver= DIRECTX7 'wrap
		SetDriver()
		CreateScreen()
	EndIf
	?
	
	If KeyHit(KEY_S) Then
		fullScreen = Not fullScreen
		CreateScreen()
	EndIf

	If KeyHit(KEY_F) Then
		useFix= Not useFix
	EndIf
	
	SetColor 100 , 100 , 230
	DrawRect MouseX() , MouseY() , 50 , 50	
	
	Flip 1
	

End Function

Function SetDriver()
	Select currentDriver
		?win32
		Case DIRECTX7
			SetGraphicsDriver D3D7Max2DDriver()
		Case DIRECTX9
			SetGraphicsDriver D3D9Max2DDriver()
		?
		Case OPENGL
			SetGraphicsDriver GLMax2DDriver()
	End Select
End Function

Function CreateScreen()
	If fullScreen Then
		screenWidth = 800
		screenHeight = 600
		Graphics screenWidth, screenHeight, 32, 60
	Else
		screenWidth = 640
		screenHeight = 480
		Graphics screenWidth, screenHeight, 0
	EndIf	
End Function

Function GetDriverString$()
	Select currentDriver
		Case DIRECTX7
			Return "DirectX 7"
		Case DIRECTX9
			Return "DirectX 9"
		Case OPENGL
			Return "Open GL"
	End Select
End Function


Last edited 2011

Last edited 2011


Grey Alien(Posted 2011) [#43]
Thanks for posting that code HrdNutz but I'm still seeing a pretty big lag on DX9 and OpenGL when compared to DX7. Your fix no doubt improves the lag by one frame's worth, but the DX9 lag is 3 frames worth by default: Check out those links I posted above and you'll see what I mean. No amount of timing code is going to fix the DX9 rendering lag, only altering the way the driver renders at a lower level will.


HrdNutz(Posted 2011) [#44]
it's a lot better, but getting it perfect is impossible; timing in blitz just isnt sensitive enough for max delay, and direct x is also doing things after the flip call but before actually presenting the screen.

when you run SLotmans example with vsync disabled the lag should be minimal and pretty much related to the driver. if you're seeing minimal lag there, then the whole problem should be in one frame. What the DX driver does with vsync enabled should be tuned for best performance.

Last edited 2011


Grey Alien(Posted 2011) [#45]
@HrdNutz: Sorry but it's not a lot better on my PC, it's only a bit better. Col's code is a LOT better because it addresses the real issue (the 3 frames being pre-rendered when vSync is being used). Check this out:

"Hi, i have a problem when i use vsync. Each frame is displayed every 16.6 ms @ 60fps. DirectX pre renders 3 frames by default giving a delay 50ms. Most GPU drivers allow you to change the pre-render limit down to 0 if needed. Nvidia is an example. Most modern games also allow you to change this and override the GPU Driver. A reason for this is some GPU's like all of intel's and some of ATI's don't have any driver control for DX9. Games like Battlefield 2 Bad Company and Counterstrike Source have options for this. If you have ever seen mouse lag on games when vsync is enabled, this is why. You can do a simple test by moving a sprite with the mouse while the hardware mouse cursor is displayed. The sprite will lag behind the mouse pointer. The Windows mouse pointer is also vsynced on the aero desktop (vista/win7) but there is no pre rendering going on so you can see the difference. This is very important for smooth gameplay and quick input response. By the way, this has nothing to do with double or triple buffering. I think microsoft call it the render queue and its a set of frames pre rendered before the double/triple buffering takes place."

From: http://area.xors3d.com/forums/viewtopic.php?f=7&t=470&start=0

This information was also backed up on other threads I found (links above) including information from NVidia.


HrdNutz(Posted 2011) [#46]
Grey, whats your monitors default desktop refresh rate? Try running the code again but in fullscreen mode @ 60Hz, Graphics 640, 480, 32, 60

im suspecting that Delay(16-frame_time) is too short for anything above 60Hz, also try enabling your fix as well.

On my PC the lag is virtually non-existent

Last edited 2011


AdamRedwoods(Posted 2011) [#47]
HrdNutz's code:
' process input and mouse after this delay
	' you want to stall as long as possible,
	' but not long enough to miss the vertical trace
	frame_time = MilliSecs() - frame_time
	Delay(16 - frame_time)
causes massive delays on my system.

The way I understand the problem is that the OS system's mouse runs on a different refresh than the app. The app would never be able to keep pace, unless we can draw the objects following the cursor at the same rate as the OS (decouple our internal drawing routine).

MY PROPOSED FIX:
Draw your own mouse cursor (looks same as OS) as a sprite and hide the OS mouse cursor when over the window.

This would slow down the cursor in the window.

Last edited 2011


HrdNutz(Posted 2011) [#48]
Adam, you're probably missing the vertical trace with that delay. This isn't really a fix, just wanted to demonstrate the problem with vsync. Try changing your delay to 15- or 14- and run in full screen at 60Hz. IMO if you can get as close as possible to vsync, you can minimize the lag, and the game will be playable.

Last edited 2011


Grey Alien(Posted 2011) [#49]
@HrdNutz: My screen refreshes at 60 so when I changed the Graphics call it didn't have any effect. When I enable the fix the lag is very small, a little bit smaller than in my first bit of code due to your code which reads the mouse coords at the last possible split second. Compare DX7 and DX9 in full-screen on your PC. If there really is no difference then you must have a) turned off VSync in your gfx card drivers so that Flip 1 in BMX isn't working (I know that this is possible as I can do it on my card), or b) somehow reduced the pre-render frames from the default of 3 to 0 on your system, or c) you aren't using the default BMX DX9 driver in BMax 1.41 or higher, or d) I have no idea what else :-)

@AdamRedwoods: I already only draw my own cursor in game and the OS cursor outside, but the problem is that players can detect the lag as the move the mouse and it annoys them, that's why I'm trying to fix the actual DX9 driver render lag instead.


AdamRedwoods(Posted 2011) [#50]
Is it just me or is this a problem common to most games? I was just playing Trine and the cursor does not keep up. OK-- I just checked Starcraft 2 and there's no cursor lag...


Ok, this sounds like a job for EVENT HOOKS!


AdamRedwoods(Posted 2011) [#51]
Decoupled the mouse drawing vs. the graphics redraw.

Honestly, I'd go with MaxGUI and use event GadgetPaint of some sort to decouple these better. I'm only using a 60hz timer, which would fall out of the VSync and cause tearing.




UPDATE: revised a bit, sorry for the mess...

Last edited 2011

Last edited 2011

Last edited 2011


Grey Alien(Posted 2011) [#52]
Unfortunately that code produces such messed up results on my PC I don't know where to begin to describe it! :-)


AdamRedwoods(Posted 2011) [#53]
Unfortunately that code produces such messed up results on my PC I don't know where to begin to describe it! :-)


try changing the buffer to single buffer mode, no backbuffer.


Grey Alien(Posted 2011) [#54]
I don't know how to do that. Plus I'm convinced that the code won't fix the lag because as I've explained it's not a problem with getting inputs faster, it's a problem with DX9 buffering several frames when Vysnc is used.


AdamRedwoods(Posted 2011) [#55]
Right-- my IDEA (though poorly executed) is that you could try to decouple the cursor refresh from your main app refresh.

it's what I'm trying to do in the above code post, by using an event trigger at 60hz, rather than the vsync.


To single buffer the screen, I just added (to the code above) after the graphics command:
Graphics screenWidth, screenHeight, 0, 60,0
or
Graphics screenWidth, screenHeight,32, 60,0 ''for fullscreen

(again, this is not the ideal fix, just trying to formulate an idea.)


If you ever notice when windows would always crap out, if you move your mouse around it would leave a trail of boxes. My assumption is that they are only refreshing a small square when the mouse moves around-- but yet, the full window of graphics is refreshed during a vsync.

This is all, speculative, and I'm known to be wrong often, plus I have to check on the chicken in the oven.


col(Posted 2011) [#56]
@Adam...

You only have to use some form of delta timing and the problem doesn't exist.
To incorporate that you have to build it into the game from the first line of code, but Grey Aliens games are finished already so thats no a real solution. Plus the fact that the lag is definitely there and very noticeable, its only a case of setting up the driver so its working 100% correct and this problem will be very minimal, agreed not completely gone, but almost unnoticeable.

EDIT - I say 'only a case of' very loosely ;o)

Last edited 2011


Grey Alien(Posted 2011) [#57]
So col, what did you make of my results?


col(Posted 2011) [#58]
Hiya Grey Alien...

I find them... interesting :o)

I'm studying this one to the point that I can almost read HEX fluently as English :o)
I'm working on kind of a 'push backbuffer' ( probably the wrong analogy as it just displays the swapchains/back buffers really fast ) system but also trying to stabilize the framerate at the same time - bit of a nightmare - kindof delta timing using swapchains :D
Not sure if it will work, but hang in there.

Being as it works on my system ok, it may be an idea just to have an option in your games, so that if the user is suffering from lag they could switch over to using a fix?

EDIT - It would have been nice if more people could try it - only 3 so far! The more systems that test it, the wider the picture we can get to give a better chance to get it much more robust on a wider range of setups.

Last edited 2011


AdamRedwoods(Posted 2011) [#59]
It would have been nice if more people could try it - only 3 so far! The more systems that test it, the wider the picture we can get to give a better chance to get it much more robust on a wider range of setups.


Intel G41, Quad core intel. Win7.

Windowed mode: dx9 still lagging a bit, dx7, opengl, not so bad.
Fullscreen mode: dx9 not as noticeable, dx7, opengl run just fine.


Grey Alien(Posted 2011) [#60]
Thanks for testing Adam, Did you notice if the green square was smooth or jerky? On mine it's jerky but enabling the original fix made it smooth, which is weird.


AdamRedwoods(Posted 2011) [#61]
Thanks for testing Adam, Did you notice if the green square was smooth or jerky?


It seemed pretty smooth on most of them, but the blue mouse square was layered behind the green square.


col(Posted 2011) [#62]
Hi all,

DOWNLOAD V0.2 HERE

Ok, this one is a skeleton version of the Dx9 engine I'm working on and I mean a skeleton version. It's still completely Bmax source, no c++ or other language.
Again this is not the BMax 2D engine. I want to see the feedback when using Dx9 outside of the BMax Max2D environment.

Some points to note...

0 - Windows only - Its to test DX9 only ( mostly Grey Aliens problems )
1 - It loads in a jpg and uses it create 2 'Sprite's.
2 - It does nothing more than setup DX9 in 800,600,32 @ 60 hz - please make sure your card/monitor can support this :-) kidding :p
3 - It's NOT a copy of Grey Aliens example in his first post. Its not the same code, it's my version, although it functions in exactly the same way.
4 - This is solely to test how smooth the lower box at the bottom is as well as the amount of lag with the cursor.

I've made 2 versions to test, one in full screen and one for windowed mode.
You may find when you first run it, it may be a little jerky for half a second or so until the GPU and example code synchronize.

It runs smooth as a baby bum in fullscreen and windowed on my system.

Sony VAIO VGN-FW31M

Last edited 2011


Grey Alien(Posted 2011) [#63]
Both crash on mine. They don't display anything. Perhaps there's a bug loading the file?


col(Posted 2011) [#64]
You do have the latest DirectX update installed I assume ?

It needs the latest version of D3D9.dll and also D3DX9_43.dll. These are both installed ( and more ) with the latest version update.

Last edited 2011


Grey Alien(Posted 2011) [#65]
I have DX11 on Windows 7. I just extracted the 3 files into a folder and run from there. The fullscreen app momentarily goes full screen then bombs. I did a search for those files and found d3d9.dll but not D3DX9_43.dll. Highest my system goes is d3dx9_34 (or d3dx10_42). Not sure I should be installed DX9 again on this system if I have DX11 or will it be fine?


col(Posted 2011) [#66]
Yes, it will be fine. It explains the crash. It specifically requires the D3DX9_43.dll library. I know you already have DX11 but that probably came pre - installed ??

The required update is...
HERE

It will only update the components that need updating. MS are still working on updates and bug fixes for the older versions. I think they've stopped updates for DX8 now but continue to update 9 , 10 and 11. The latest update is June 2010 so far.
[EDIT]No fear as it will only update components of all 3 versions that need updating. You won't 'go back to Dx9 only', so to speak.

Basically you need Dx9.0c to run the test code.

I had the same problem with the Dynamic Cube Mapping Demo I wrote to test this engine. Not sure if you looked at it HERE
Only 1 person had a problem with it and they were in exactly the same situation as you now. They needed to update too and it worked fine after.

Last edited 2011


Grey Alien(Posted 2011) [#67]
OK thanks, installing it now. Thing is, for a BMax solution to this problem, it will need to work on older DX9...


Grey Alien(Posted 2011) [#68]
Results:

Windowed mode - small lag on cursor, not too bad. Dark green square is very jerky indeed.

Full-screen mode - no lag on cursor at all. Dark green square is jerky (not as bad as windowed mode but still bad).


col(Posted 2011) [#69]
It was only a test to see how the technique worked outside of the BMax2D environment.
Strange how its silky smooth on my machine.

I think as it varies in quality from one machine to another, a real solution is to have the user select an option to help the mouse lag or not? Whats your thoughts on that?

My last code simply pads out any spare time between vwaits in the GPU, so it doesnt do the extra renders to create any lag.


Grey Alien(Posted 2011) [#70]
It is weird how it can be so different on our machines, sounds like a good idea but doesn't work in practice on enough machines (well we could do with some more tests).

As for having an option, well a lot of people don't ever check the options, especially in casual games, so sales may still be lost anyway by people who dislike lag.

What I did in my latest Spring Bonus build was add an option to turn off the custom cursor and switch back on the system cursor - this way they won't get mouse lag. Also I used the grabpixmap fix mentioned in the first post to at least improve full-screen mode.


col(Posted 2011) [#71]
Hey Grey Alien,

Just to let you know that I tried another method, by using DirectInput to control the mouse and using an image as a pointer, and that doesnt work too, it suffers from the lag when not using VSync.

Oh if it did work, it would have been easy to incorporate back into BMax without using the D3DX stuff, that was just to load a texture and use the sprite features to display the texture. If it worked and its moulded back into BMax, then you would just revert back to using DrawRect or DrawImage as normal.

But on this issue.... I'm all out of suggestions at this time unfortunately. Sorry.
Maybe in the future if I have a brain wave then I'll give it another go, but until then...

[EDIT]There is one advantage to using my DirectInput code in that you can introduce a 'multiplier' to adjust the mouse sensitivity to make the mouse move very fast or very slow independent of the system mouse. Of course the idea is to hide the system mouse, but then its no problem to do this technique already in existing Bmax2D code by using a multiplier with mouse*speed().
Anyway DirectInput is Win32 specific. I was thinking the main problem is DX9 which is of course Win32 specific too.

Last edited 2011


Grey Alien(Posted 2011) [#72]
Thanks for trying so hard on this col, it was really appreciated! For now I've stuck with the simple fix from the first post that reduces lag in full-screen DX9/OGL but not in windowed mode.


AdamRedwoods(Posted 2011) [#73]
http://www.gamedev.net/topic/580048-dx9-vsync-lag/

Direct3D supports hardware mouse cursors:
http://www.gamedev.net/topic/457105-mouse-lag-under-directx9/


My original thought on this is to use double-buffered mode, but when drawing a cursor to draw immediately to the front buffer on mousemove. Possible on opengl with glDrawBuffer(GL_FRONT) and glFlush() instead of using Flip()/SwapBuffers(). Overall, this would probably cause a little streaking, and to prevent this, just do a grabimage, etc.

Last edited 2011


Grey Alien(Posted 2011) [#74]
Thanks Adam. The 3 frame lag is also mentioned in that thread. I don't just need to solve the mouse lag problem because of course they keyboard feels like it lags too, so would a joystick all because of the display lag.


therevills(Posted 2011) [#75]
Hey Jake,

Can you please tell me where you added the DX9 "fix":

		Local MouseHack:TPixmap
		MouseHack = GrabPixmap(1, 1, 1, 1)


in your framework?

Cheers!


Grey Alien(Posted 2011) [#76]
Before ccFlip. See that other thread you started.


Noobody(Posted 2011) [#77]
Hi,

Windowed Mode (fix off):
- DX7 Blue square lags a little bit.
- DX9 Blue square lags a little bit.
- OpenGL Blue square lags a little bit.

Windowed Mode (fix on): Fix doesn't seem to do anything at all

Fullscreen Mode (fix off):
- DX7 Blue square lags a little bit.
- DX9 Blue square is incredibly jerky and lags behind a lot.
- OpenGL Blue square lags behind quite a bit

Fullscreen Mode (fix on):
- DX7 No change
- DX9 Blue square is a lot better, almost as good as DX7
- OpenGL Blue square still lags behind quite a bit

The green square is smooth in all cases.


I modified your code a bit to improve the OpenGL case; it works by calling glFinish, which forces all graphics commands in the queue to complete before the application resumes. Just replace your current useFix block by this
If useFix Then
	If currentDriver = OPENGL  Then
		glFinish()
	ElseIf currentDriver = DIRECTX7 Or currentDriver = DIRECTX9 Then
		Local MouseHack:TPixmap
		MouseHack = GrabPixmap(1, 1, 1, 1)
	EndIf
EndIf


On my machine, this really helps improve the lag on the blue square down to pretty much DX7 levels. Let me know whether it works for you.

I checked and the concept of glFinish does not seem to exist in DirectX - your version with grabbing a small pixmap and thus locking the backbuffer seems to be pretty much the only solution. Another way is to put an event into the DX command stream right after flip and then busy wait for the event to complete. This way you're never too much ahead of the GPU frame-wise and decrease the lag to a minimum.


Grey Alien(Posted 2011) [#78]
Thanks for the tip! I'll investigate it.


Jur(Posted 2011) [#79]
These fixes eliminate mouse lag but the price is lower frame rate, which is now in the range of DX7 on my system. Still it is much better that way, thanks.


therevills(Posted 2012) [#80]
I've just found this article:

http://my.opera.com/Vorlath/blog/2009/02/01/directx-d3d-mouse-lag

He talks about a fix which uses an "occlusion query" and to make sure that the request ends AFTER the Present() call...

Does anyone has any idea how to do that? (And have any idea what he is talking about? ;))


Grey Alien(Posted 2012) [#81]
Added a comment on that thread too.


Grey Alien(Posted 2012) [#82]
Also @therevills, did you ever try that glFinish code change above? I never got round to testing it yet.


therevills(Posted 2012) [#83]
Nope I havent tried it, since the main issue I think is DirectX lag... I havent seen much (if any) lag on OpenGL.


Grey Alien(Posted 2012) [#84]
I was definitely getting the lag in GL (see results at top). Shame as I thought the issue was just a DX issue, but clearly it's not, it's some kind of graphics pipeline thing.


therevills(Posted 2012) [#85]
What I've read is that we will always get input lag when using vsync, we just got to try and find ways around it - or just turn vsync off :/


therevills(Posted 2012) [#86]
I've just tried something...

I added "Delay(17)" to my main loop, so we would lose 1FPS and now the lag is gone!!!


17 because 1000(ms)/60(fps) = 16.666667

Any one care to try it?

Last edited 2012

Updated example:


Last edited 2012

Last edited 2012


Grey Alien(Posted 2012) [#87]
This must mean the CPU isn't pushing the GPU too hard. Plus of course you are only getting 30FPS now.


therevills(Posted 2012) [#88]
Nope - getting 58/59 FPS, we are only losing 1FPS - I added an FPS counter ;)

Last edited 2012

Heres my results with delay(17):

DX7 Window: No lag - 30FPS!?!
DX7 Full Screen: No lag - 58FPS

DX9 Window: No lag - 55FPS-58FPS
DX9 Full Screen: No lag - 58FPS

OpenGL Window: No lag - 58FPS
OpenGL Full Screen: No lag - 58FPS

So DX7 doesnt like a delay over 15 in window mode...

I actually tried this fix as on a gaming forum for RO2 players were complaining about input lag with vsync and one user suggested to alter the ini file and limit the FPS to 59.9...

Last edited 2012


Zeke(Posted 2012) [#89]
yep. dx9 with delay 17 i get 55-58fps and no lag.

if using fullscreen this "Delay(17)" fix works. constant FPS: 58 in all graphics modes.. if using fix FPS drops to constant 55.

but if using windowed. dx7 lags a lot, 30FPS. dx9 and gl lags a little. but still 50fps. fix have no difference.

so
if fullscreen then Delay(17)


but of course it depends what kind game you are coding.

Last edited 2012


Grey Alien(Posted 2012) [#90]
Does the <50 FPS look jerky though? It surely shouldn't look smooth if frames are being dropped every so often.


therevills(Posted 2012) [#91]
30FPS does look jerky, 50+FPS looks fine.

@Zeke, when you say windowed dx7 lags a lot - is it the mouse cursor and the blue square out of sync or just the bad framerate? Also when you say "Using the fix" I guess you are talking about pressing F.

I'm thinking now to do something like this:

desktopRate = GetDesktopRefreshRate()
delayAmount = Ceil( 1000 / Float(desktopRate) )

if graphicsDriver = OPENGL or DIRECTX9
   Delay(delayAmount)
end



col(Posted 2012) [#92]
Hey guys,
It looks like you're on the road to fixing this up, nice one!! but just for kicks I made an example that uses the D3DOCCLUSION_QUERY as suggested in the link by therevills at post #80.

I fear it may suffer inconsistent results across various machines as in the previous codes I wrote due to it's using a similar algo but its worth a look, no? :-)

Just an .exe for the moment as its a modified brl/d3d9graphics.bmx file... runs silky smooth with zero lag on my machine in Win7 and Vista in fullscreen without using the 'F' key fix. Note this is just a Dx9 fix.

Laters.

oh yeah, the link is... http://www.datafilehost.com/download-54b3668c.html
EDIT:- with therevills FPS counter...http://www.datafilehost.com/download-a0a22136.html

Last edited 2012


therevills(Posted 2012) [#93]
Hey Dave,

When I run the LagTest.13.01.2012.exe and change drivers to DirectX9 (as it starts in DX7) all I get is a black screen and nothing responds...

Can you share the code you added to d3d9graphics.bmx?


col(Posted 2012) [#94]
yeah sure.... the complete modified d3d9graphics.bmx file....



Last edited 2012


col(Posted 2012) [#95]
Modifications are at..
Line 21
Lines 102..108
Lines 122..123
Line 132
Lines 138..142
Lines 381..395


therevills(Posted 2012) [#96]
Cheers Dave :) I used KDiff (<3 KDiff) to find the changes ;)

Okay got it to work with DX9 (not sure whats wrong the your exe Dave)... but I still see a small amount of lag with DX9, about the same with the grab pixel fix - I'll have to test it with the work PC on Monkey ;)

Last edited 2012

Last edited 2012


Grey Alien(Posted 2012) [#97]
I remember testing some of col's code before and it failed because I had the wrong version of some DX files installed, so that could be it.


Grey Alien(Posted 2012) [#98]
So the occlusion code is a no go? :-(

Seems testing on a wide based on machines is key and also making sure people know exactly what to look for.


col(Posted 2012) [#99]
Thats cool.

It sounds like it might entering an infinite loop in the Flip function during the While..WEnd of the query at Lines 387 and 388, you could squeeze in a 'get out' clause in between them, may/may not work as it the device shouldnt be lost at this stage, anyway you could make it look like this...


While _d3dOccQuery.GetData( Varptr pixelsdrawn,4,1 )=1 'D3DGETDATA_FLUSH
If _d3dOccQuery.GetData( Varptr pixelsdrawn,4,1 )<0 Exit
Wend


oh!! Line 393 should really before the Endif at Line 390 !!!

@Jake
Hey Jake, this is just regular Dx9 stuff. No need for the latest versions etc.

EDIT:-Crossposting... Im too slow :D

Last edited 2012


therevills(Posted 2012) [#100]
@Jake - The occlusion code looks the same as the grab pixel code... I need to test it on that dodgy GPU at work.

@Dave - can you show us the Flip method with these changes, as I've got a blank line at 393.


col(Posted 2012) [#101]
uh huh...




therevills(Posted 2012) [#102]
Ah so just the Issue(2) within the IF statement - ta... testing now.


Results:

Looks nice and smooth, slight lag same as the GrabPixel fix - will test on Monkey.

Thanks for showing us how to do this Dave.

With my fix (delay(17)) I get zero lag but it does hurt the frame rate a tiny bit.

Last edited 2012


col(Posted 2012) [#103]
Its only that if it did work acceptably and you release to the public, then say the _d3dOccQuery for whatever ends up Null, it would cause a crash at that point, keeping it within the If..EndIf makes sure it will be only called when the query pointer is valid. Also notice the extra line between While..WEnd in there.


col(Posted 2012) [#104]
With your Delay... fix I get zero lag unless the delay >= 16 ( Its obvious why this is ;-) ). Anything under that its silky smooth and no lag in all drivers, although the FPS shows under 60FPS ( around 55-56 ), I think it may just be inaccuracies in the algo timings. It looks like a better fix all round so far :P

Last edited 2012


therevills(Posted 2012) [#105]
Also notice the extra line between While..WEnd in there.
Yep I saw that ;)


therevills(Posted 2012) [#106]
I get zero lag unless the delay >= 16 ( Its obvious why this is ;-) ). Anything under that its silky smooth and no lag in all drivers, so it looks like a better fix all round so far :P


Sorry Dave, I've read this a few times over...

Are you saying that you get zero lag if the delay is greater or equal to 16, but anyway less (under) than 16 you get silky smooth and also no lag... I'm now confused :S

Last edited 2012


col(Posted 2012) [#107]
Sorry for the confusion :D

My bad use of the math symbols.

Less than 16 and everything is silky smooth as expected. otherwise the framerate halves with generally bad stuttering.

Last edited 2012


therevills(Posted 2012) [#108]
Okay... so with delay<=16 you still get zero lag? With your fix or mine?

So whats the better fix all round then?


col(Posted 2012) [#109]
I get good results with using your fix on its own, and a good result with my fix on its own. I get outstandingly absolute zero lag with both.

If I had to use only 1 fix, I'd use yours as its generic across all drivers, my fix is Dx9 only.

Fundamentally my fix works the same way as the GrabImage fix, which is it pretty much forces the GPU to render any queued up commands that are waiting to be rendered. Using GrabImage forces this same thing because you're asking GPU to read back what is in the backbuffer, so it needs to finish all rendering to get an accurate result. My fix just waits until all rendering in the pipeline is completed before continuing, ending up with the same result really :P


therevills(Posted 2012) [#110]
Think we are getting there... so you would use my fix - Delay(17)... but you said "otherwise the framerate halves with generally bad stuttering" if you use Delay(17)...

(BTW we really need a chatroom function with this forum to talk back and forward better)


col(Posted 2012) [#111]
Using your code...

DirectX7:-
Delay 0 to 17, the mouse pointer stays near the top left of the moving square, but lags more and more as the Delay moves closer to 0. At 17 the lag is almost non-existant.

DirectX9:-
Delay 0 to 15, the mouse pointer stays exactly at the top left of the moving blue square with very little lag while super smooth and FPS shows 55-56. I'm sure its actually getting to the real Flip at the this point ( ie 60FPS ) because its so smooth.
Delay 16, It looks like its playing catchup inbetween frames. Its smooth then jerky, then smooth and so on.
Delay 17. Horrific stuttering. 29-30FPS.

OpenGL:-
Delay 0 to 16, horrific lag. Worse of them all. Like really bad.
Delay 17. Almost zero lag.

On all drivers, going higher than Delay 17 causes the FPS to drop which then causes very noticable stuttering with the movement. No mouse lag though! although the effect is not nice, so a definite no go there.

Totally agree with the chatroom idea ;-) Archived so that others could also read the conversations at a later date too. Mods.... where are you ;-)

Last edited 2012


therevills(Posted 2012) [#112]
Cool - thanks for Dave.

Whats PC are you testing on? (CPU,GPU etc)

On mine (specs in sig), I get no lag with delay 17, but the "catchup" now and again with all drivers. When I go into window mode with DX7 I get 30FPS.

I wonder if we could set delay to 16.6667 if it would be any better... I can't find the code which does the delay stuff, it looks like an extern calling bbDelay, but I can't find bbDelay.


Grey Alien(Posted 2012) [#113]
Btw, I like how the new test shows up the lag really clearly so no one can say it's not there.

Here are my results with therevills code:

**DirectX7:
Full screen:
Delay 0 to 14 = lag but very smooth movement (62FPS)
Delay 15 = this is the crossover point where it mostly lags but sometimes is in sync and the movement has occasional jitters
Delay 16 = lag disappears, more jerkiness. (55-58FPS)
Delay 17 = lag gone, even jerkier. (52-55FPS)
Delay 18+ = lag gone, horrible jerky, decreasing FPS.

Windowed mode:
Delay 0 to 12 = lag + jerky + 62 FPS (windowed mode never used to be jerky when I got Blitz to sort out the VSync years ago but I think they changed it again).
Delay 13+ = lag (never goes away), jerky as hell, FPS begins to plummet.

**Direct X9:
Full Screen:
Delay 0 to 15 = lag (bigger than DirectX7) but very smooth movement (62FPS)
Delay 16 = this is the crossover point with mostly lags and some jitters.
Delay 17 = lag gone but jerky. (58 FPS)
Delay 18+ = lag gone, worse jerkiness, declining FPS

Windows mode:
Delay 0 to 15 = lag (bigger than DirectX7 but smaller than Full Screen mode) but very smooth movement unlike DirectX 7 in windowed mode(62FPS)
Delay 16 = crossover point with mostly lag + occasional jitter
Delay 17 = lag is reduced but doesn't completely go away like in Full screen mode (58 FPS)
Delay 18+ = small lag still, worse jerkiness, worse FPS

**OpenGL
Basically exactly the same as DX9

Last edited 2012


therevills(Posted 2012) [#114]
Oh on another note, I've just tested my Mac Mini and there isnt any need for any kind of "fixes" as it there isnt any lag in Fullscreen mode or Window mode.

Which is kind of strange, as I would have thought the whole vsync/input lag would be the same on a Mac...


Grey Alien(Posted 2012) [#115]
Yeah up higher I say that I tested the old code on Mac and saw no lag in Full screen and maybe a tiny bit in windowed. Need to test your more obvious code.

From my tests on my PC, I'd prefer to run the game without any delay because as soon as the delay reaches approx 1 frame (16.66666ms) jerkiness begins to occur and only gets worse. Plus if you write a game with varying amounts of CPU stuff happening per frame, you can't work out how much the delay should be (well maybe approx. if you checked millisecs). I really don't feel this is a solution.

It also sounds like the occlusion code won't do anything different from the original fix in my code at the top, although definitely test it on your work PC @therevills and see if it halves the framerate. What I'd like to know really is if you took 100 PCs with varying video cards, how many the lag fix was horrible on.

Also big thanks to you two for keeping on trying different things! It's cool.

Last edited 2012


col(Posted 2012) [#116]
Thats cool.

Those results are on a Sony Vaio VGN-FW31M - Win7 x64. The results were very similar using the same machine and Vista x86 ( 32bit ).


I wonder if we could set delay to 16.6667 if it would be any better... I can't find the code which does the delay stuff, it looks like an extern calling bbDelay, but I can't find bbDelay


How about setting a timer to 60 then waiting for the timer before Flip ? This would remove any varying timings? By varying I mean timings that are different across machines caused by varying cpu/gpus speeds and configs. The above example doesnt really push the gpu and isnt a realistic load on the cpu/gpu. As the load increases there will be less time for the cpu to take advantage of fixed Delay(s). Just throwing spanners in the works :D


Delay (bbDelay) uses the OS 'sleeping' mechanisms so any spare time is returned to the system - brl.mod/blitz.mod/blitz_app.c


Grey Alien(Posted 2012) [#117]
@Col Sounds like you are also saying that varying CPU load will throw a spanner in the works. For me the lag ONLY goes away when jerkiness begins and that's not a compromise I'd like to do.

[EDIT]

So what are the options for PC?

1) Looks smooth on most machines with no lag (original fix) and crappy on a few (unknown how big "few" is)
2) Jerky on most with no lag (Delay fix)
3) Have no lag fix and a hardware mouse cursor (not good for keyboard based games or where mouse is used to draw/drag).
4) Or, ahem, go back to DX7 which had minimal lag. Problem is no VirtualRes stuff will work and that's bad for scaling down games on modern netbooks (= lost sales)
5) Test out DX10/11+ and see if any better and force customers to upgrade (bad idea for casual market)

No point switching to OpenGL as that acts same as DX9.

Last edited 2012


therevills(Posted 2012) [#118]
How about setting a timer to 60 then waiting for the timer before Flip

Nice idea... just tried it. Set at 60 I get the same lag. When I set it as 58 I get a tiny bit of lag, but a tad jerky...

brl.mod/blitz.mod/blitz_app.c

I must start removing the file filter off my search...
I must start removing the file filter off my search...
I must start removing the file filter off my search... ;)

So what are the options for PC?

6) Use Dave's occlusion query (only for DX9)
7) Turn vsync off

Last edited 2012


col(Posted 2012) [#119]
Using therevills code...
I just think that if using a 'fixed Delay' value, as the load increases, then there will be less time between frames, hence the required delay would need to be less. EDIT :- Different loads and different cpu speeds means a different Delay required?

I guess an automatic dynamic frame counter incorporated into the 'Delay' would help to prevent such problems? Maybe also a manual override like therevills has in his example code. Would people be put off by manually setting up the game timing ( using a one time initial setup screen ) on first time use? The delay mechanism gives the best 'all round' result for me.

@Jake BTW what system specs do you have there?

I just tested the examples above on Dx10/Dx11 driver and it suffers the same amount of lag as Dx9. The same fixes above fix it by the same amount too. I've not incorporated any multi-threading into it yet ( to keep it Dx10 compatible ), but I dont think it'll get rid of it anyway. The multi-threading helps when it comes to uploading into the GPU. It wont really help with render lag, if anything it could make it worse.

Last edited 2012


col(Posted 2012) [#120]

Set at 60 I get the same lag.



Is that when using any 'fixes', or when using Jakes first example?


therevills(Posted 2012) [#121]
Is that when using any 'fixes',


Nope, no fixes apart from a Timer...

Global timer:TTimer = CreateTimer(60)


	
	WaitTimer( timer )

	Flip 1

	Delay(1)


Last edited 2012


therevills(Posted 2012) [#122]
So Monday came around a bit too fast...

Anyway as promised - testing Dave's occlusion query on this work PC specs:

CPU: Intel Core 2 Duo E8400 @ 3GHz
GPU: NVIDIA Quadro NVS 290
RAM: 2GB
OS: Windows 7 32bit

Going thru the motions:

DX7 Window: Slight lag - 62FPS
DX7 Window with Grab Pixel Fix: Slight lag - 62FPS
DX7 Full Screen: Slight lag - 62FPS
DX7 Full Screen with Grab Pixel Fix: Slight lag - 62FPS

(This is where Dave's occlusion query comes into play)
DX9 Window with occlusion query fix: Slight lag - 62FPS
DX9 Window with Grab Pixel Fix and occlusion query fix: Slight lag - 62FPS
DX9 Full Screen with occlusion query fix: Slight lag - 62 FPS
DX9 Full Screen with Grab Pixel Fix and occlusion query fix: Slight lag - 40FPS

OpenGL Window: No lag - 62FPS
OpenGL Window with Grab Pixel Fix: No lag - 62FPS
OpenGL Full Screen: No lag - 62FPS
OpenGL Full Screen with Grab Pixel Fix: No lag - 62FPS

Looks good :) (well its not perfect but a lot better - same as DX7 I would say)

Last edited 2012

And without the occlusion query:

DX9 Window: Slight lag - 62FPS
DX9 Window with Grab Pixel Fix: Slight lag - 62FPS
DX9 Full Screen: HUGE lag - 62 FPS
DX9 Full Screen with Grab Pixel Fix: Slight lag - 40FPS

Last edited 2012

Last edited 2012

Last edited 2012


Grey Alien(Posted 2012) [#123]
Wow that's interesting, so the occlusion fix gives better performance than grab pixel on that work PC right? Seems like that could be the best solution then. A module tweak rather than some top level code. I wonder if BRL would consider adding this as an official tweak, perhaps with a flag called "fixRenderLag" or something?


therevills(Posted 2012) [#124]
so the occlusion fix gives better performance than grab pixel on that work PC right?


Yep, just to clarify - the occlusion fix helps the mouse lag and runs at 62FPS, the grab pixel helps the mouse lag but runs at 40FPS.

I've got one more test to run for this occlusion fix, I've got an old PC running Windows XP with DirectX8 installed. I'm going to install DX9 (so install SP2) and see how that handles this fix - from memory its got an intel onboard GPU...

perhaps with a flag called "fixRenderLag" or something?


This is exactly what I am going to add :)

Last edited 2012


therevills(Posted 2012) [#125]
Just installed Windows XP SP2 with Directx9c on an oldish/slowish PC:

CPU: Intel Celeron E1200 @ 1.6GHz
GPU: Intel G33/G31 Express
RAM: 2GB
OS: Windows XP SP2

DX7 Window: No lag - 62FPS
DX7 Window with Grab Pixel Fix: No lag - 62FPS
DX7 Full Screen: Slight lag - 62FPS
DX7 Full Screen with Grab Pixel Fix: Slight lag - 62FPS

(This is where Dave's occlusion query comes into play)
DX9 Window with occlusion query fix: Slight lag - 62FPS
DX9 Window with Grab Pixel Fix and occlusion query fix: Slight lag - 62FPS
DX9 Full Screen with occlusion query fix: Slight lag - 62 FPS
DX9 Full Screen with Grab Pixel Fix and occlusion query fix: Slight lag - 62FPS

OpenGL Window: Cant tell the lag! - 500FPS!?!?!?!?
OpenGL Window with Grab Pixel Fix: No lag! - 333FPS!?!?
OpenGL Full Screen: No lag - 250FPS
OpenGL Full Screen with Grab Pixel Fix: No lag - 333FPS


So not sure whats happening with the OpenGL there (not waiting for the vertical sync!?), but the occlusion query fix works fine on this PC.


So I think I am going to do the following:
If driver=DIRECTX7 or driver=OPENGL
  useGrabPixelFix = True
Else
  ' dont use grab pixel fix for DirectX9 due to poor performance on some pcs
  useGrabPixelFix = False
End If
' Using modified BlitzMax DirectX9 driver which does an occlusion query 



therevills(Posted 2012) [#126]
Oh and I've added the flag to BlitzMax so you can turn it on and off when you want:

In brl.mod/graphics.mod/graphics.bmx add UseDX9RenderLagFix:
Public

Global GraphicsSeq=1
Global UseDX9RenderLagFix% = 0 ' new boolean


And in brl.mod/dxgraphics.mod/d3d9graphics.bmx:
	Method Flip( sync )
		Local present = _graphics.Flip(sync)
		If UseDX9RenderLagFix Then
			Local pixelsdrawn
			If _d3dOccQuery
				_d3dOccQuery.Issue(1) 'D3DISSUE_END
				
				While _d3dOccQuery.GetData( Varptr pixelsdrawn,4,1 )=1 'D3DGETDATA_FLUSH
					If  _d3dOccQuery.GetData( Varptr pixelsdrawn,4,1 )<0 Exit
				Wend

				_d3dOccQuery.Issue(2) 'D3DISSUE_BEGIN
			EndIf
			'Can read back pixelsdrawn if really wanted :P
		End If
		
		Return present
	End Method


Thanks again Dave for the OccQuery :)


col(Posted 2012) [#127]
Very interesting results going on there with the OpenGL driver. I had a similar thing happen one time on Vista. It seemingly just started to happen. I re-installed BMax and it fixed it. I really don't know why it happened because I'm generally playing the Dx drivers :/

That's cool the occlusion query is working out ok :P


Grey Alien(Posted 2012) [#128]
Yeah really cool, thanks Dave and therevills for sorting that out, pretty epic teamwork there. Guess there's no reason not to add this then.

Last edited 2012


therevills(Posted 2012) [#129]
I've tested this on 3 Nvidia GPUs and 1 Intel... can anyone test the occlusion query on an ATi GPU?


col(Posted 2012) [#130]
Thanks Jake and therevills,

For completeness, in the Flip method, I do think this line is redundant and can be safely removed :-

If _d3dOccQuery.GetData( Varptr pixelsdrawn,4,1 )<0 Exit

Reason being... logically, if the return value at the line before ( the While ) equals 1 ( which is a FAIL value ) then the loop is continued. Any other value and the loop ends anyway, which make the 'If ... <0' test redundant. I only added it in thinking that the code was entering an infinite loop on therevills machine, but it appears to be a busted .exe in the download.

You don't 'need' to remove it, but it is redundant and a bit pointless :D

Have fun :-)

Last edited 2012


col(Posted 2012) [#131]
The Gpu is ATI in my laptop :)


therevills(Posted 2012) [#132]
Excellent so we can (hopefully) say it works with Nvidia, Intel and ATi :)

I'm just going to leave that line in at the moment as I've spent far too long on this issue testing multiple machines etc, and I know that with that line it works, but I do agree it "looks" redundant ;)

I've uploaded an exe if anyone else would like this:

http://diddy.googlecode.com/files/dx9.debug.zip

Last edited 2012


Grey Alien(Posted 2012) [#133]
Works great on my PC. Both fixes work fine in full-screen DX9, no difference. In windowed mode the fixes do nothing but the lag is less. Shame we can't fix windowed mode too.

I forgot to post my specs:

Intel i7 870 (Quad core @ 2.93GHz)
4 GB RAM
Windows 7
NVidia Geforce GTX 460
DX 11 installed


col(Posted 2012) [#134]
Taking on some ideas and info from DStastny....

I've added a couple of lines to disable aero in code using the A key for testing in Windowed mode. I'll look into the Flush method he proposes too...

Results:
Dx7 - Zero lag ( as opposed to some lag )
Dx9 - Same tiny lag as Dx7 when in full screen. A definite improvement but small and acceptable is there instead of BIG lag.
Opengl - VSync seems switched off, so fast the FPS returns negative EDIT:- Not sure what happened there but its OK now :D EDIT2:- I've worked out that if started in windowed mode then going to the OpenGL driver the FPS goes crazy, but after going FullScreen then back to windowed the FPS is OK ( this is with Aero DISABLED ) :/



Last edited 2012


therevills(Posted 2012) [#135]
Yep I've just done the same :)

The only issue here is that it disables the whole desktop and on mine I get a Window 7 popup message: "The color scheme has been changed to Windows 7 Basic"

I've read that DirectX3D 9Ex is meant to help the Aero lag too... but I didnt even know about DX9Ex until this morning...

http://msdn.microsoft.com/en-us/library/windows/desktop/ee890072%28v=vs.85%29.aspx#flip_model

Also it looks like a Windows 7 only thing...


col(Posted 2012) [#136]
Yep the 9Ex is Win7 only. Would it be a little premature to make a Win7 only driver, not enough users in the real world just yet?

DirectX is a HUGE api, and Direct3D is only a part of it and thats still BIG.

No matter what method I use to disable Aero ( in the app icon or in code ), the whole desktop gets disabled, not just the app window?, except for I get the message when using the code. There might be a method to suppress the message. I'll look...


BlitzSupport(Posted 2012) [#137]

The only issue here is that it disables the whole desktop and on mine I get a Window 7 popup message: "The color scheme has been changed to Windows 7 Basic"



As far as I'm aware, that's perfectly normal when a single app requests to disable Aero. You can't have it only for some apps.


Grey Alien(Posted 2012) [#138]
That won't be acceptable unfortunately, we definitely can't fiddle with users' desktops. Shame!


therevills(Posted 2012) [#139]
Okay guys, I've gone back to frame limiting... can you give this a try please:



You will need the code from post #126 if you want to test the DX9 Fix - or you can download the exe from here: http://diddy.googlecode.com/files/dx9.debug_test_2.rar

Play around with the framerate_limit, I'm thinking about setting it to 59...


col(Posted 2012) [#140]
Hiya,

Interesting...

I assume you want just windowed results with this one as the fullscreen is 'fixed enough to be acceptable' ??...

Using the code ( not the .exe )...

All drivers...
Every second I get a jump in the movement and the delay amount looks like its 'resetting' or i should say recalculating the timing delay. The FPS counter also reflects this by going from a steady 62 to 58 for a tiny number of frames, 1, 2 or maybe 3 frames at the most. Probably not really relevant as its only for the 1st second ( until timings are established? ) it has terrible lag. The 'long term' lag is about the same as the original Dx7 lag in full screen, but with Dx9 there is a tiny amount more lag, not much but with a keen eye you can see it - I don't think Joe Public would be able to see this difference.

These 3 results include the above 'every second' hesitation...

OpenGL - is smoothish with the equivalent of the same amount of lag in the original Dx7 lag, but the squares and cursor seem to be moving slightly faster than the Dx drivers?? maybe its me :/ lol. During the hesitation the delay figure is altered but its too fast to what it changes to as it can only be for about 1 or 2 frames.

Dx7 - not as smooth as OpenGL, quite jerky actually especially while the figures are changing :- at the hesitation point the Delay figure increases from 0.000 to 8.000 over a number of frames then goes back to zero until the next hesitation. Using this driver the Delta figure also changes at the hesitation frame but only for 1 frame as its too fast to see the figure.

Dx9 - smoothest of them all, at the hesitation point the Delay changes to about 8.xxxx then over a number of frames ( very very fast ) steps up to 13.666666 and holds that.

Altogether, the 'hesitation' is causing bad problems.

Edit:- Oh yeah... playing with the framerate_limit makes matters worse for me no matter what the figure is.

Sony Vaio VGN-FW31M.

Last edited 2012


therevills(Posted 2012) [#141]
Yeah its not perfect, I've added it to my game and it seems acceptable as more is happening on the screen you can't really tell the little hiccups - and yes this is just to fix window mode.

This frame limiting code is meant to be a copy of the max_fps commands you find in 3D engines like source and tech3 (quake). If any one can come up with a better/smoother limiter that would be great :)


col(Posted 2012) [#142]
I got taken away from this without try the Flush method for use with Dx9 windowed. This doesn't disable Aero. While it doesn't eliminate the lag completely, on my system (Sony Vaio Win7-x64 and with Vista-x86 ) it definitely improves the issue. See what you guys think...

Turn off all 'fixes' then use F4 to toggle with the Dx9 driver. EDIT: On my system this also improves the lag on the GL driver too when windowed, but it slaughters Dx7 windowed performance by halving the FPS.



Last edited 2012


therevills(Posted 2012) [#143]
Hey Dave.... so what does the Flush/DwmFlush do?

http://msdn.microsoft.com/en-us/library/windows/desktop/dd389405(v=vs.85).aspx

Issues a flush call that blocks the caller until the next present, when all of the Microsoft DirectX surface updates that are currently outstanding have been made. This compensates for very complex scenes or calling processes with very low priority.


Errrrr.... wut ?! Also why does it help OpenGL!?!?! O_o

Just tested on my main PC - looks good for DX9 and OpenGL... it kills DX7 (drops the FPS to 30, DX7 doesnt lag too much in Window mode anyway).

And I've just tested on my WinXP box... It crashes as soon as you enable "AeroFlush"...

Last edited 2012


col(Posted 2012) [#144]
I stand to be corrected here :-) but as I understand it...

its very similar to how the same fix can work in fullscreen mode. Aero uses the GPU to accelerate the effects, so in effect it gets a similar render queue( or even becomes a part of the Dx render queue? ) The DwmFlush command forces it to render all calls in the dx render queue before carrying on. The fullscreen methods use a similar approach but use different techniques which ( as a side-effect ) force the render queue to be rendered ( emptied/flushed ). Doing this every frame reduces the lag caused by 'render ahead'.

EDIT: Although after reading the Remarks section on the MSDN link for the command, it says that it doesn't do that!! but only seems to render any changes in the queue. wtf does that supposed to mean?!?! haha. I don't know, MS eh :P

Last edited 2012


col(Posted 2012) [#145]
Sorry about the crash :/

I've edited the code to prevent it. Line 174.

As for GL... Aero uses Dx to add a layer of 'Aero Effects' on top of the existing desktop display. I'd imagine that a window thats using GL will have just that portion of the screen using the GL context, and the rest uses Dx?

Last edited 2012


therevills(Posted 2012) [#146]
Dont apologise!!

Thank you for keep helping!

(Also I just read that DwmFlush minimum supported client is Windows Vista, so I should have guessed it would have crashed on XP!! And of course Desktop Window Manager is only for Vista onwards...)

This fix looks good, I'll have to test it on a few more PCs - (esp. the work PC)

Last edited 2012


therevills(Posted 2012) [#147]
So just to recap the current good "fixes":

For Fullscreen Mode

DirectX9

Occlusion Query fix

(Not Grabpixel due to poor performance on some PCs)

DirectX7

Grabpixel fix

OpenGL

Grabpixel fix

For Window Mode - Lag caused by Aero

DirectX9

DwmFlush fix (FlushAero)

DirectX7

Grabpixel fix

(Not DwmFlush due to poor performance on some PCs)

OpenGL

DwmFlush fix (FlushAero) / Grabpixel fix

---------------------------------

If fullScreen Then
	If driver = DIRECTX9
		OcclusionQuery
	ElseIf driver = DIRECTX7
		GrabPixel
	ElseIf driver = OPENGL
		GrabPixel
	EndIf
Else
	If driver = DIRECTX9
		FlushAero
	ElseIf driver = DIRECTX7
		GrabPixel
	ElseIf driver = OPENGL
		FlushAero and GrabPixel
	EndIf
EndIf


Is this about right?

---------------------------------

What a mess!!! LOL

Last edited 2012


col(Posted 2012) [#148]
Seems about right until we're told otherwise.

To keep your main code cleaner I suggest to package the lagfix up as a TLagFix type?
That way you could keep all the decision making 'If's and ElseIf's out of the main loop, and in the main loop simply call one function which then calls the appropriate lag fix code. I doubt this will increase the speed of the code but your working code would be a lot cleaner and easier to read.

EDIT:- Some 'working pseudo code' maybe something along the lines of...



Last edited 2012


therevills(Posted 2012) [#149]
Yep that sounds like a good idea :)

I've just tested the FlushAero on my work pc and it looks good, now the lag is small when Aero is enabled.

Window Mode (Aero Enabled)

Without Flush Aero:

DirectX11 - Huge lag - 62FPS
OpenGL - Small lag - 62FPS
DirectX7 - Small lag - 62FPS
DirectX9 - Huge lag - 62FPS

With Flush Aero:

DirectX11 - Small lag - 62FPS
OpenGL - Small lag - 62FPS
DirectX7 - Small lag - 30FPS
DirectX9 - Small lag - 62FPS

(I've recently added Col's DirectX11 driver to my BlitzMax setup ;))

Last edited 2012


Grey Alien(Posted 2012) [#150]
Interesting research and fixes guys! Good stuff. Yeah so when BMax supports DX11 by default I guess we'll have to go through all this stuff again!!

So am I correct that it's only safe to call FlushAero on Vista and above? Do we have to check it's not XP or lower ourselves or will it simply do nothing on XP?


therevills(Posted 2012) [#151]
Yeah so when BMax supports DX11 by default I guess we'll have to go through all this stuff again!!


Maybe.... but with the testing I've done, I think the OcclusionQuery Fix will work for it fine.

I'm thinking we will do this all again when Windows 8 is released! ;)

FlushAero on Vista and above? Do we have to check it's not XP or lower ourselves or will it simply do nothing on XP?


Yep FlushAreo is only safe on Vista and 7. The IF statement: "If DwmapiDLL" will return false on an XP machine so it doesnt run the FlushAero command.


Grey Alien(Posted 2012) [#152]
I'm thinking we will do this all again when Windows 8 is released! ;)
Agreed and possibly other framework updates as eventually the portals will demand compliance as part of their QA tests.

Thanks for the info about FlushAero.


col(Posted 2012) [#153]
Hiya,

Yesterday, I found a bug in the D3D11 driver that only occurs in fullscreen mode. When exiting from the driver and then trying to use another Dx driver ( as in the example in post 142 ), it would a crash with an EAV. Funny thing is that if it went back to windowed mode then it will still crash, but ONLY if you went into fullscreen mode at some point! Starting and staying in windowed mode didn't cause any problems. I love those!!

EDIT:-

After messing around with GitHub for an hour, I think I've uploaded it correctly :P
https://github.com/SRSSoftware/d3d11max2d.mod

EDIT:- The latest update includes the render lag fix for windowed and fullscreen modes.

Last edited 2012


col(Posted 2012) [#154]
...

Last edited 2012


therevills(Posted 2012) [#155]
Cool! Thanks Dave!

I notice that the DX9 query is quite different to the DX11 query...


col(Posted 2012) [#156]
I notice that the DX9 query is quite different to the DX11 query...


Yep, both Dx10 and Dx11 apis are completely different to Dx9, and require a different approach to what's been used in all previous Dx versions.

You may have noticed some extra ( interesting? ) files in the d3d11max2d/ folder too that aren't yet finished ;-)


therevills(Posted 2012) [#157]
There might be an issue with the DirectX9 OcclusionQuery stuff... I've just got a bug report from Big Fish Games:

"The game crashes when resuming from sleep mode while in fullscreen mode (does not happen while in windowed mode). "


That's the only information I have and I can't test right now, but my guess is that the OcclusionQuery is causing the issue...


therevills(Posted 2012) [#158]
Just testing now and it displays "_d3dDev.Reset failed" when returning from sleep mode...

[edit]Nope its not the OcclusionQuery stuff as I've just installed a fresh copy of BlitzMax and it does it on that too :(

Last edited 2012


col(Posted 2012) [#159]
Ive been testing too, using the vanilla setup without occlusion queries. Its failing before it actually powers down going into sleep mode, and then of course after waking it won't recover.

Try commenting out the Throw "_d3dDev.Reset failed" and see if it works successfully. It works for me . I'm looking into it though. Might have something to do the WM_SIZE, not sure yet - it seems to have something to do with the fullscreen losing focus and max2d bailng out.

Last edited 2012


col(Posted 2012) [#160]
Anyone else not using Win7 having this issue?

To replicate, you can use any code that puts D3D9 into fullscreen mode, while in fullscreen, put the pc into sleep mode, then wake it up again.

EDIT:-
Can you ask them for the system spec they were using, os and gpu?

If it turns out it Vista/Win7 we can use the D3D9Ex interfaces that dont suffer from lost devices.

Last edited 2012


Grey Alien(Posted 2012) [#161]
@col and @therevills

Just revisiting this thread as I never fully implemented the OcclusionQuery fix. Now I come to look at d3d9graphics Flip() and it doesn't look the same due to the DX9 sleep/restore fix mentioned here ( http://www.blitzbasic.com/Community/posts.php?topic=96638 ). I'm using BMax 1.48. So how should I add in the OcclusionQuery code safely to the new Flip() method? Thx!

Also @therevills I read your recap on comment #147 and thought I'd better point out that GrabPixel fix isn't needed for DX7 as it makes no difference. DX7 is always fine. So the options look like this:

If fullScreen Then
	If driver = DIRECTX9
		OcclusionQuery
	ElseIf driver = DIRECTX7
		Nothing
	ElseIf driver = OPENGL
		GrabPixel
	EndIf
Else
	If driver = DIRECTX9
		FlushAero
	ElseIf driver = DIRECTX7
		Nothing
	ElseIf driver = OPENGL
		FlushAero
	EndIf
EndIf


Last edited 2012


therevills(Posted 2012) [#162]
Jake I had a PC at work where you could see the lag using DX7 and the GrabPixel helped.

I havent upgraded to 1.48 yet. But here are the changes in my 1.44b files, just beware that there are two flip methods in d3d9graphics:

d3d9graphics.bmx








graphics.bmx
Added boolean just before BumpGraphicsSeq function:
Global UseDX9RenderLagFix% = 0 ' new boolean


I think thats it...

Last edited 2012


therevills(Posted 2012) [#163]
Just looked at the d3d9graphics.bmx in v1.48 and merged it my version:



You should just be able to copy the above and overwrite the file... and just add the new boolean in graphics.bmx.

(The above code contains the lag fixes and the sleep crash fix)

Last edited 2012


Grey Alien(Posted 2012) [#164]
Re: DX7 lag, I went through the whole thread looking for any evidence of grabpixel improving (or worsening) DX7 and there doesn't seem to be any.

You even posted this about your work PC:

DX7 Window: Slight lag - 62FPS
DX7 Window with Grab Pixel Fix: Slight lag - 62FPS
DX7 Full Screen: Slight lag - 62FPS
DX7 Full Screen with Grab Pixel Fix: Slight lag - 62FPS


Which infers no change right? You can see why I'm confused :-)

Last edited 2012


Grey Alien(Posted 2012) [#165]
Anyway thanks for the merge! I didn't realise the OcclusionQuery went in the second flip in the file which is where I was getting confused :-)


therevills(Posted 2012) [#166]
You can see why I'm confused :-)


Yeah, totally ;) I've got a spread sheet somewhere which details a bunch of tests I did at the time and one of the results showed the grabpixel fix helped a DX7 machine.

I think we can pretty safe these days to drop DX7 anyway.

Anyway thanks for the merge!

No problem...

You seem like you are working on something again Jake... any clues? ;)


Grey Alien(Posted 2012) [#167]
Cool, well I'll take your word for it that DX7 needs the grab pixel fix but I might leave it out of my version simply because back in the day BRL added a pretty good lag fix for DX7 (it used to be bad) and I don't want to overload it with a second fix. I'm just being paranoid :-)

Well mainly I've been fixing up my framework with stuff that was well overdue like finishing off the lag test stuff, fixing some DX alt+tab crashes, adding in widescreen support etc. Plus looking into Windows 8 and Gatekeeper on Mountain Lion to figure out what kind of code-signing I have to do to stay up to date. This is all so I can put updated games on my site and send them to portals to make sure that the epic long tail of my games can continue a bit longer. I don't want these games to die prematurely due to having out of date tech as the OSes move forward.

All that of course puts me in a good position to make a new casual game, and really I need to do that ASAP to bring in some money as moving back from Canada was expensive, and I have some great ideas ready to roll. However, for a short while I'm going to do lots of monkey stuff, more "indie"-style games, so I can relive my teenage years and see if I can make anything of it. If it goes well I'll continue and leave casual behind, if not, I'll be back on casual until I have more money to do more indie stuff again. Now is the golden age of indie and I want to be part of it.

There you go, hope that wasn't TL:DR.