Performance Issues with SharpDX and D3DImage

◇◆丶佛笑我妖孽 提交于 2019-12-24 08:58:05

问题


I have a control that uses D3DImage to host a SharpDX DirectX9 surface and allows use to pan, zoom, and interact with world objects and the result is really awesome. Performance is actually an amazing consistent 60fps EXCEPT when the window is minimized and brought back up or the user locks and then unlocks the screen. When the window regains focus the fps drop to about 25-30fps. I can "fix" the issue by unloading and loading the control back into its container and then BOOM, 60fps.

I call the main render function using a DispatcherTimer set at 10ms. Before, I was using the CompositionTarget.Rendering event but performance wasn't as good as using the DispatcherTimer. I fairly certain that I'm handling lost resources correctly. Any ideas about these missing frames per second?

EDIT: I am having this same exact problem. Unfortunately, doing an automatic device reset doesn't fix the issue but if I have a button that executes the same reset method then my fps goes back to normal.


回答1:


Locking / Unlocking the screen causes a device lost. But you probably know that.

Anyway I use D3DImage in WPF as well. My performance problems ended when I called

D3DImage.SetBackBuffer(D3DResourceType.IDirect3DSurface9, IntPtr.Zero)

on each device lost. I used to have responsiveness issues after a device lost until I realized WPF was still holding a reference to a texture. Of course you should later re-set the backbuffer when you have an updated texture.

Although it is unclear what exactly is going wrong behind the scenes, it is clear that D3DImage keeps a refcount to your texture, which can prohibit a successful recovery in the case of a device lost. In my case, we simply had no updates.

Sorry for the anectodal answer... But until a real D3DImage expert enters the room, it's better than nothing.

P.S. I am using SlimDX but I don't think it matters... For all that I know SharpDX is a fork of SlimDX.




回答2:


There's an overload to SetBackBuffer that takes an additional Boolean flag:

D3DImage.SetBackBuffer(D3DResourceType, IntPtr, Boolean)

When you call the SetBackBuffer(D3DResourceType, IntPtr) overload, or call the SetBackBuffer(D3DResourceType, IntPtr, Boolean) overload with the enableSoftwareFallback parameter set to false, the [WPF] rendering system releases its reference to the back buffer when the front buffer becomes unavailable and nothing is displayed.

I'm no expert either, but I would guess that this is what's happening; Because you didn't set that flag to 'true', WPF is calling Release() on what happens to be the last COM ref count for your D3D surface as soon as it exits the lock. This would seem to require that you be maintaining an additional ref count of your own.

For one thing, I've noticed that, even after getting your "used" surface "back" from a WPF lock/unlock round-trip, you need to still not release it until your next surface takes its place (i.e. in a successful call to d3dimg.SetBackBuffer). Otherwise, you'll get flickering when the WPF window is dragged around the screen. Given that that's the only reliable method I've discovered for detecting when WPF is truly done with your buffer, it does seem pointless for WPF to be concerned with AddRef'ing or Release'ing it.

What's generally confusing with D3DImage is that the IDirect3DDevice9 that's running WPF is not really associated with the IDirect3DDevice9 that generated the surface you're putting forth as a back buffer... for WPF. The whole Lock/Unlock business is presumably for WPF's benefit, and has nothing to do with your own (possibly lockable?) IDirect3DSurface9 rendertarget's survival.


Beware!
If using D3DImage.TryLock, beware of its, um... shall we say, unconventional semantics: You must call Unlock even in the case where TryLock returns false. For more information, see https://stackoverflow.com/a/39581727/147511.



来源:https://stackoverflow.com/questions/13368940/performance-issues-with-sharpdx-and-d3dimage

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!