+ Reply to Thread
Page 1 of 2 1 2 LastLast
Results 1 to 30 of 33

Thread: Mouse Lag! Can I render cursor to front buffer? (DX8)

  1. #1
    Senior Member
    Join Date
    Apr 2006
    Posts
    1,200

    Default Mouse Lag! Can I render cursor to front buffer? (DX8)

    Hello,

    I'm using DirectX8, I notice quite a bit of mouse lag if I render a sprite from the mouse cursor (in contrast to the non-lagged hardware mouse cursor).

    So, is it possible to render sprites to the front buffer (or the back-buffer that's about to become the front-buffer on d3ddevice->present).

    I'm trying to get a smooth, responsive, mouse cursor that's a sprite.

    That make sense?

  2. #2
    Senior Member
    Join Date
    Feb 2009
    Location
    Finland
    Posts
    355

    Default

    IIRC, you can reduce mouse lag by locking a surface (or other GPU resource) that's being used in a frame. That'll sync CPU and GPU thus reducing the lag. That's what we had in Splinter Cell, well.. until I removed it

  3. #3
    Senior Member
    Join Date
    Apr 2006
    Posts
    1,200

    Default

    Thanks.

    Isn't the lag caused by having multiple back-buffers in a swap chain? So the mouse pointer is always like 3/60th second behind where it should be? (that's assuming a refresh frequency of 60hz).

    Maybe that's not the cause then?

    You're suggesting I just lock any texture? (not the back or front-buffer etc).

  4. #4

  5. #5
    Senior Member
    Join Date
    Feb 2009
    Location
    Finland
    Posts
    355

    Default

    Problem is because command/push buffer contains more than one frame of data, so CPU is essentially several frames a head of GPU (this is different from double/triple buffering). By locking a resource that's being used by GPU will force syncing of CPU and GPU, because resource can't be locked until the GPU has processed it. This is what you want to generally avoid, but it can be an option for reducing the lag.

    Edit: slight correction, there are lock flags which you can use to prevent CPU-GPU syncing (e.g. D3DLOCK_DISCARD and D3DLOCK_NOOVERWRITE), so it's better not to use those for the purpose (:

    Edit x 2:
    Quote Originally Posted by Jamie W View Post
    You're suggesting I just lock any texture? (not the back or front-buffer etc).
    You could lock backbuffer, but then you have to (at least in DX9) create the backbuffer with D3DPRESENTFLAG_LOCKABLE_BACKBUFFER, which may cause other kinds of performance loss, and IIRC you can't lock front buffer (at least in DX9).
    Last edited by JarkkoL; 07-23-2009 at 03:41 PM.

  6. #6
    Senior Member
    Join Date
    Jul 2004
    Location
    Isle of Wight, UK
    Posts
    3,773

    Default

    Can you not just settle for a custom GDI cursor ?
    Regards,
    Paul Johnson

    [Great BIG War Game: iOS | Android] [Great Little War Game: iOS | Android] [Fruit Blitz: iOS | Android] [Yachty Deluxe: iOS | Android]

  7. #7
    Senior Member
    Join Date
    Jan 2005
    Location
    Argentina
    Posts
    602

    Default

    Quote Originally Posted by Applewood View Post
    Can you not just settle for a custom GDI cursor ?
    http://www.southwindsgames.com/blog/...-direct3d-lag/

  8. #8
    Senior Member
    Join Date
    Apr 2006
    Posts
    1,200

    Default

    Thanks for all the info an suggestions everyone.

    Yea, I much prefer to use a regular sprite (texture blit) for my mouse cursor. I want to have full colour and full range of alpha etc. So much more you can do that way with animating it etc (check out the mouse pointer in Pogacha's plane game, as a good example).

    I came across this article on NVidias' site.

    ow should I handle input lag (that is, apparent mouse and keyboard response time) in situations where the CPU is getting too far ahead of the GPU?

    The most obvious solution would be to lock the back buffer for each frame in Direct3D (analogous to calling glFinish() in OpenGL). This ensures that all pending graphics commands are completed by the GPU before the CPU moves on. However, this completely removes any potential for asynchronous processing, as the CPU is unable to process the next frame until the current frame has finished rendering.

    A better solution is double-buffered texture locking. This is a generalization of locking the back-buffer. At the end of your frame you render a single triangle to a tiny (2x2) texture, then read the contents of your texture. So far this solution is equivalent to locking the back-buffer, and suffers the same kind of stalls. It ensures that the GPU never gets more than 1 frame ahead of the CPU.

    Now generalize it: use two tiny textures and alternately render to them and alternately lock them:

    Render frame 1

    Render a triangle to texture 0

    Lock and read texture 1

    Render frame 2

    Render a triangle to texture 1

    Lock and read texture 0

    Render frame 3

    Render triangle to texture 0

    Lock and read texture 1

    Render frame 4

    Render a triangle to texture 1

    Lock and read texture 0

    ...

    Now, the GPU does not get stalled; it also never gets more than 2 frames ahead of the CPU. Lag is up to one frame, but overall efficiency is higher since the GPU is always busy (if you are GPU bound). You can further generalize it to use triple-buffered textures, and you may even be able to insert multiple sync points per frame to get finer control over lag.
    Which sounds like it wont halt the CPU so much, as just locking the back-buffer (assuming I understand correctly!).

    So I'm creating 2 small renderable textures for the job, and having other issues (D3D device throws a wobbly when I toggle in to full-screen, I think it's related to creating a renderable texture that's got POOL_DEFAULT). Still investigating..

  9. #9
    Senior Member
    Join Date
    Feb 2009
    Location
    Finland
    Posts
    355

    Default

    Quote Originally Posted by Jamie W View Post
    Which sounds like it wont halt the CPU so much, as just locking the back-buffer (assuming I understand correctly!)
    Actually, that technique stalls the CPU as much, but it wont stall the GPU, which is a good thing. Double buffering the tiny texture will have one frame more lag though, but it's probably a tolerable trade off.

  10. #10
    Senior Member
    Join Date
    Jan 2005
    Location
    Argentina
    Posts
    602

    Default

    Quote Originally Posted by JarkkoL View Post
    Actually, that technique stalls the CPU as much, but it wont stall the GPU, which is a good thing. Double buffering the tiny texture will have one frame more lag though, but it's probably a tolerable trade off.
    Done it correctly it will just stall your game pipeline, you can ask to lock it with no_wait, and do a Sleep(0) in the middle.

  11. #11
    Senior Member
    Join Date
    Feb 2009
    Location
    Finland
    Posts
    355

    Default

    Well, the whole idea is to stall your CPU so I don't see much of a point using D3DLOCK_DONOTWAIT.

  12. #12
    Senior Member
    Join Date
    Jan 2005
    Location
    Argentina
    Posts
    602

    Default

    Quote Originally Posted by JarkkoL View Post
    Well, the whole idea is to stall your CPU so I don't see much of a point using D3DLOCK_DONOTWAIT.
    It will depend if you use a multhreading engine ... in my case I use a separated thread for audio so I need the CPU to not be frozen.

  13. #13
    Senior Member
    Join Date
    Feb 2009
    Location
    Finland
    Posts
    355

    Default

    It doesn't stall the entire CPU but just the thread where D3D is called from, so it's not an issue with multi-threaded engine. In fact, it's better to not use the no-wait flag for multi-threaded engine because waiting with spinlock consumes 100% of the CPU and doesn't let other threads to utilize the resource, while without the flag D3D potentially sleeps the thread until GPU has processed the required data.

  14. #14
    Senior Member
    Join Date
    Apr 2006
    Posts
    1,200

    Default

    It's all a bit over my head.

    I'm also having a problem with I create a texture with POOL_DEFAULT (not POOL_MANAGED), when I do a D3Ddevice->Reset (after I toggle windowed <> full screen), it's throwing a wobbly.

    Do I need to reload or something, all my POOL_DEFAULT textures after I've done a D3Ddevice->Reset?

  15. #15
    Senior Member
    Join Date
    Feb 2009
    Location
    Finland
    Posts
    355

    Default

    IIRC, you have to recreate D3DPOOL_DEFAULT resources upon device reset.

  16. #16
    Senior Member
    Join Date
    Apr 2006
    Posts
    1,200

    Default

    So...

    1. Release all D3DPOOL_DEFAULT resources.
    2. Reset Device.
    3. Recreate all D3DPOOL_DEFAULT resources.

    Or is there no need to release them at stage 1?

    I'm gonna have a play around with it..

  17. #17
    Senior Member
    Join Date
    Feb 2009
    Location
    Finland
    Posts
    355

    Default

    You could also check IDirect3DDevice9::Reset() from DX SDK docs yourself

  18. #18
    Senior Member
    Join Date
    Jan 2005
    Location
    Argentina
    Posts
    602

    Default

    Quote Originally Posted by JarkkoL View Post
    It doesn't stall the entire CPU but just the thread where D3D is called from, so it's not an issue with multi-threaded engine. In fact, it's better to not use the no-wait flag for multi-threaded engine because waiting with spinlock consumes 100% of the CPU and doesn't let other threads to utilize the resource, while without the flag D3D potentially sleeps the thread until GPU has processed the required data.
    Well, I was assuming that the driver "might" stall the entire CPU ... in my approach I'm not doing it nor allowing the driver to do it ... but if there is some guarantee that the driver won't do it (?) I would go with the WAIT flag.

  19. #19
    Senior Member
    Join Date
    Aug 2007
    Posts
    1,554

    Default

    I have to say, with your recent pc/mac development, it's looking more like Blitzmax would be a good choice for you long term. Would probably solve alot of these low level problems and allow you to concentrate on just the game code.

  20. #20
    Member
    Join Date
    Jul 2004
    Location
    Derby, England
    Posts
    93

    Default

    Quote Originally Posted by JGOware View Post
    I have to say, with your recent pc/mac development, it's looking more like Blitzmax would be a good choice for you long term. Would probably solve alot of these low level problems and allow you to concentrate on just the game code.
    I was skim reading this thread, painfully remembering the time I wasted on crap like this and wondering if recommending blitzmax would really be appreciated at this point. But you got there first

    I've yet to get myself a mac and see how easy it is to set up (and avoid some of the minor Win-only pitfalls that workarounds already exist for), but common knowledge says "it just works".

  21. #21
    Senior Member
    Join Date
    Jan 2005
    Location
    Argentina
    Posts
    602

    Default

    Quote Originally Posted by matibee View Post
    I was skim reading this thread, painfully remembering the time I wasted on crap like this and wondering if recommending blitzmax would really be appreciated at this point. But you got there first

    I've yet to get myself a mac and see how easy it is to set up (and avoid some of the minor Win-only pitfalls that workarounds already exist for), but common knowledge says "it just works".
    err ... but blitmax guys do also have this problem
    http://www.blitzbasic.com/Community/...hp?topic=58192

  22. #22
    Senior Member
    Join Date
    Apr 2006
    Posts
    1,200

    Default

    It's a tricky one, if to use (depend on) some other platform/engine etc, or if to go for a more direct approach. I think one downside with using a third party engine, is when something doesn't work, or doesn't do something in the way you want it to. You're kinda stuffed. Also, there's an element of inflexibility.

    There's upsides too of course, but for me, I don't think think the upsides compensate for the lack of control etc.

    I got the smooth cursor working now, by locking the back-buffer. Seems to work fine, though I'm still not entirely sure what the cost of doing this is!..

    Thanks once again for all your help and suggestions.

  23. #23
    Senior Member
    Join Date
    Feb 2009
    Location
    Finland
    Posts
    355

    Default

    Quote Originally Posted by Jamie W View Post
    It's a tricky one, if to use (depend on) some other platform/engine etc, or if to go for a more direct approach. I think one downside with using a third party engine, is when something doesn't work, or doesn't do something in the way you want it to. You're kinda stuffed. Also, there's an element of inflexibility.
    Depends if the 3rd party engine is closed vs open source engine. Personally, I wouldn't develop a game with closed source engine if I had a choice.

  24. #24
    Senior Member
    Join Date
    Sep 2004
    Location
    San Jose, CA.
    Posts
    1,726

    Default

    Quote Originally Posted by Jamie W View Post
    I got the smooth cursor working now, by locking the back-buffer. Seems to work fine, though I'm still not entirely sure what the cost of doing this is!..
    The cost is that you're losing parallel processing between the CPU and GPU. This could end up being a big deal on slower systems, so you'll probably want to switch over to the 2x2 method at some point.
    Peter Young | www.attitudegain.com | Linkedin | Twitter

    Projects:
    Meridian 59: Evolution
    ???
    ???

  25. #25
    Senior Member
    Join Date
    Apr 2006
    Posts
    1,200

    Default

    Quote Originally Posted by vjvj View Post
    The cost is that you're losing parallel processing between the CPU and GPU. This could end up being a big deal on slower systems, so you'll probably want to switch over to the 2x2 method at some point.
    The 2x2 method is definitely better then?

    Thanks.

  26. #26
    Senior Member
    Join Date
    Feb 2009
    Location
    Finland
    Posts
    355

    Default

    Yes, because:
    1) you don't have to create back-buffer with D3DPRESENTFLAG_LOCKABLE_BACKBUFFER flag
    2) because you have option to double buffer the texture thus having the GPU stalling less
    Sorry if I wasn't clear enough in my previous posts

  27. #27
    Senior Member
    Join Date
    Sep 2004
    Location
    San Jose, CA.
    Posts
    1,726

    Default

    Quote Originally Posted by Jamie W View Post
    The 2x2 method is definitely better then?

    Thanks.
    Overall it's generally better than locking the backbuffer, yes. Locking the BB causes a pretty big drop in performance, so you're kinda sacrificing one aspect of playability for another. The 2x2 method is kinda hacky, but at least you'll get parallel processing and input lag won't go above a frame (which is pretty standard for most games).

    The best method is probably to use DX event queries, but those are DX9-only, I believe.
    Peter Young | www.attitudegain.com | Linkedin | Twitter

    Projects:
    Meridian 59: Evolution
    ???
    ???

  28. #28
    Senior Member
    Join Date
    Apr 2006
    Posts
    1,200

    Default

    Quote Originally Posted by JarkkoL View Post
    Sorry if I wasn't clear enough in my previous posts
    Nah, you've been great thanks Jarkko, it's just me being dim!

  29. #29
    Senior Member
    Join Date
    Apr 2006
    Posts
    1,200

    Default

    Quote Originally Posted by vjvj View Post
    Overall it's generally better than locking the backbuffer, yes. Locking the BB causes a pretty big drop in performance, so you're kinda sacrificing one aspect of playability for another. The 2x2 method is kinda hacky, but at least you'll get parallel processing and input lag won't go above a frame (which is pretty standard for most games).
    Sweet, will use the 2x2 double buffered texture method then!..

    Quote Originally Posted by vjvj View Post
    The best method is probably to use DX event queries, but those are DX9-only, I believe.
    I only went for DX8, because I figured it would be compatible with a larger range of PCs. I wonder what the percentages are, how many PCs with DX8 (rather than DX9 or above).

    Does anyone know if there's any data on this anywhere?

  30. #30
    Senior Member
    Join Date
    Feb 2009
    Location
    Finland
    Posts
    355

    Default

    If user doesn't have DX9 installed, you can ask them to upgrade, or bundle DX9 redistributable with your game if it's not too much of an overhead. My guess is that if someone has DirectX installed at all, it's pretty rare that they haven't upgraded to DX9 within the past ~6 years.

+ Reply to Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts