hecomi / uDesktopDuplication

Desktop Duplication API implementation for Unity (only for Windows 8/10)
http://tips.hecomi.com/entry/2016/12/04/125641
MIT License
557 stars 97 forks source link

Unity rendering crashes from monitor capture #35

Open CurtisVL opened 4 years ago

CurtisVL commented 4 years ago

Under some circumstances, Unity's rendering will fail when trying to initialize (Enable the object of) a monitor capture.

Log will show errors like so: d3d11: failed to create buffer (target 0x1 mode 0 size 128) [0x887A0005]

And as I use RenderTextures in some places they fail to render also: D3D11: Failed to create RenderTexture (620 x 800 fmt 9 aa 1), error 0x887a0005

This results in the application no longer rendering anything. From some research, that error code implies the graphics driver crashed, yet, everything else on the system seems to work as intended.

This issue seems to arise when the system is under heavy GPU load, but not out of VRAM to be clear, the hitch caused by initializing monitor capture triggers this to happen, or sometimes it just displays the 'Unsupported display' error briefly while freezing the application before recovering.

Any assistance in resolving this would be greatly appreciated!

(Current Unity project version is 2019.3.0b7, though issue persisted on latest 2019 stable build too - This issue is hard to reproduce, sometimes it'll happen on application startup, other times when enabling a capture's GameObject)

hecomi commented 4 years ago

Thank you for the report! But for now I have not been able to identify where the problem is... (maybe GPU crash?) If you find something new about this, or create small example that can cause this error, please let me know.

CurtisVL commented 4 years ago

Hi Hecomi!

This error is very hard to reproduce, but can be common for some users! To the point of it will crash the application due to all the rendering fails it causes, then on re-launch it'll repeat the same process as soon as a monitor capture is enabled.

The error code implies a GPU crash as you stated, however, other games the user is playing will be performing fine at the time of this, typically just under very heavy GPU load.

I'm not sure this is helpful, but it appears to be from enabling multiple monitor captures on the same frame I believe. This causes a large hitch whilst the desktops are initializing and something about that seems to break it.

Sorry I can't be more helpful! I'll keep you up to date if I find more information about this or a way to reproduce it. :)

CurtisVL commented 4 years ago

Hi Hecomi,

I'm unsure if this is the same issue, but it presented the same crash within Unity that freezes rendering, this is uDesktopDuplication log file's entries: https://pastebin.com/ajgfPrKg

These are the main errors it throws: Monitor::Initialize() => GetDpiForMonitor() failed.

Duplicator::UpdateMoveRects() => DXGI_ERROR_ACCESS_LOST.

Duplicator::Duplicate() => DXGI_ERROR_ACCESS_LOST.

Duplicator::Duplicate() => DXGI_ERROR_INVALID_CALL.

Is it possible to ensure a blank texture is returned when these errors occur to avoid the rendering freeze?

(In this case, the person resolved the issue by restarting their system as they had just installed new GPU drivers)

hecomi commented 4 years ago

Thanks for sharing an useful log! I'll check it and implement a fallback not to break the rendering.

CurtisVL commented 4 years ago

Hi again Hecomi!

I have some further information that could help find the cause of the issues where Unity's rendering will freeze. A user of my software had the Windows 'Play HDR games and apps' setting enabled, this would freeze the rendering as soon as the application started a monitor capture. (Though, many other users having this issue don't have this setting enabled, it just freezes Untiy's rendering also!)

Application log file, as well as crash logs are attached. Player.log error.log

This section caught my eye, running in one of the threads: Call Stack for Thread 3856: 0x00007FFBB5A344C4 (win32u) NtGdiDdDDIAcquireKeyedMutex2 0x00007FFBB30D6A32 (d3d11) D3DKMTQueryResourceInfo 0x00007FFBB30D06F8 (d3d11) D3DKMTQueryResourceInfo 0x00007FFBB311122D (d3d11) D3DKMTQueryResourceInfo 0x00007FFBB46A3C9D (dxgi) PIXEndCapture ERROR: SymGetSymFromAddr64, GetLastError: 'Attempt to access invalid address.' (Address: 00007FFBA98E5EC2) 0x00007FFBA98E5EC2 (uDesktopDuplication) (function-name not available) ERROR: SymGetSymFromAddr64, GetLastError: 'Attempt to access invalid address.' (Address: 00007FFBA98E5B80) 0x00007FFBA98E5B80 (uDesktopDuplication) (function-name not available) ERROR: SymGetSymFromAddr64, GetLastError: 'Attempt to access invalid address.' (Address: 00007FFBA98E74E7) 0x00007FFBA98E74E7 (uDesktopDuplication) (function-name not available) ERROR: SymGetSymFromAddr64, GetLastError: 'Attempt to access invalid address.' (Address: 00007FFBA98E54D9) 0x00007FFBA98E54D9 (uDesktopDuplication) (function-name not available) 0x00007FFBB6A70E72 (ucrtbase) beginthreadex 0x00007FFBB6B77BD4 (KERNEL32) BaseThreadInitThunk 0x00007FFBB8B0CED1 (ntdll) RtlUserThreadStart

Let me know if I can help further in any way!

hecomi commented 4 years ago

Hi CurtisVL,

Thank you for providing the log and sorry for my late reply.... Now I work from home due to the COVID-19 and the progress of private projects is not good. So, the investigation of this problem will be not so soon but I'll try my best. I'm gald if you wait for it.

Curtis-VL commented 4 years ago

Hi Hecomi,

Thanks for getting back to me! Take as long as you need.

In the meantime, I wrote an error logger for my application that will show the past 100 'Lib' calls before the application's rendering failed, so far 2 crashes have been submitted to me, the files are attached. report_1586844354.txt report_1586853492.txt Files are formatted as 'Class: Lib.SomeMethod(parameterUsedInUnity)', so 'Monitor: Lib.GetTop(id)' is 'Lib.GetTop(id)' somewhere in Monitor.cs.

I notice about half way into both logs I see this: Monitor: Lib.SetTexturePtr(id, texturePtr_) Monitor: Lib.GetRenderEventFunc()

This seems to be the only common call between both reports and around the same time. Could this be the point of failure?

Curtis-VL commented 4 years ago

Maybe Unity is trying to access the texture before it's written as uDesktopDuplication is using threading? Or maybe it's writing as Unity is reading? I'm unsure how native plugins work I'm afraid!

This would line up with why it happens under heavy GPU or CPU load though, such as in game loading screens.

Curtis-VL commented 4 years ago

Actually, after looking at some new reports, the issue doesn't seem to be linked to a specific API call: report_1586936136.txt report_1586940131.txt

Maybe as I suggested above Unity could be trying to access something before it's written/whilst it's being written? Causing the access violation error seen in the log in some cases.