Azure / azure-remote-rendering

SDK and samples for Azure Remote Rendering
MIT License
107 stars 39 forks source link

[Remote rendering problem] InvalidOperationException: An error occurred: Failed (1) on Windows Standalone #70

Closed WikkidEdd closed 2 years ago

WikkidEdd commented 2 years ago

When running on a Standalone Windows build of our app we got the following error at the point of connecting to an ARR session accompanied by the screen going black. We're struggling to get a solid repro for it. it's happened twice each time on a different computer.

This error repeated every frame. It's possible there was a more useful error before it, but our remote logs are capped at a certain length so we can't see before it. We'll keep trying to reproduce it locally so we can get the full logs.

InvalidOperationException: An error occurred: Failed (1)
Microsoft.Azure.RemoteRendering.NativeLibraryHelpers.CheckStatus (System.UInt64 handle, Microsoft.Azure.RemoteRendering.status value) (at <00000000000000000000000000000000>:0)
Microsoft.Azure.RemoteRendering.Unity.RemoteManagerUnity.get_IsConnected () (at <00000000000000000000000000000000>:0)
HybridRenderingPassFeature+HolographicRemotingCallbackPass.Execute (UnityEngine.Rendering.ScriptableRenderContext context, UnityEngine.Rendering.Universal.RenderingData& renderingData) (at <00000000000000000000000000000000>:0)
UnityEngine.Rendering.Universal.ScriptableRenderer.ExecuteRenderPass (UnityEngine.Rendering.ScriptableRenderContext context, UnityEngine.Rendering.Universal.ScriptableRenderPass renderPass, UnityEngine.Rendering.Universal.RenderingData& renderingData) (at <00000000000000000000000000000000>:0)
UnityEngine.Rendering.Universal.ScriptableRenderer.ExecuteBlock (System.Int32 blockIndex, UnityEngine.Rendering.Universal.ScriptableRenderer+RenderBlocks& renderBlocks, UnityEngine.Rendering.ScriptableRenderContext context, UnityEngine.Rendering.Universal.RenderingData& renderingData, System.Boolean submit) (at <00000000000000000000000000000000>:0)
UnityEngine.Rendering.Universal.ScriptableRenderer.Execute (UnityEngine.Rendering.ScriptableRenderContext context, UnityEngine.Rendering.Universal.RenderingData& renderingData) (at <00000000000000000000000000000000>:0)
UnityEngine.Rendering.Universal.UniversalRenderPipeline.RenderSingleCamera (UnityEngine.Rendering.ScriptableRenderContext context, UnityEngine.Rendering.Universal.CameraData cameraData, System.Boolean anyPostProcessingEnabled) (at <00000000000000000000000000000000>:0)
UnityEngine.Rendering.Universal.UniversalRenderPipeline.RenderCameraStack (UnityEngine.Rendering.ScriptableRenderContext context, UnityEngine.Camera baseCamera) (at <00000000000000000000000000000000>:0)
UnityEngine.Rendering.Universal.UniversalRenderPipeline.Render (UnityEngine.Rendering.ScriptableRenderContext renderContext, UnityEngine.Camera[] cameras) (at <00000000000000000000000000000000>:0)
UnityEngine.Rendering.RenderPipelineManager.DoRenderLoop_Internal (UnityEngine.Rendering.RenderPipelineAsset pipe, System.IntPtr loopPtr, System.Collections.Generic.List`1[T] renderRequests) (at <00000000000000000000000000000000>:0)

Any thoughts appreciated.

ChristopherManthei commented 2 years ago

Hi @WikkidEdd , what is happening here is that the session is no longer valid so our call fails. We will add a fix in the next release to handle this more gracefully. In the meantime you can change the IsConnected function in RemoteManagerUnity.cs to return: return CurrentSession != null && _instance.Session.Valid && _instance.Session.IsConnected; However, the actual problem here is that an invalid session is set to RemoteManagerUnity.Session. As the RenderingSession class holds a reference to the native object, the only way I can think of to create this situation is to dispose the RemoteRenderingClient which will turn all RenderingSession objects created from it invalid. If you are calling dispose on the RemoteRenderingClient, can you make sure to set the active session in the RemoteManagerUnity to null again? We will check our code to see if there are any edge cases in which we miss that on our side, e.g. ARRServiceUnity. Just as a precaution, can you try setting RemoteManagerUnity.CurrentSession = null; after stopping sessions and destroying clients in your code? Cheers, Christopher

WikkidEdd commented 2 years ago

Some more information: One of the users to whom this happened, logged in twice with the same account so our backend gave the same ARR session out twice. This means they got "RRException: Trying to open a session while a session already exists is not supported in ARRUnityService." on one of the devices resulting in the Invalid Session. It's on our backlog to support this scenario, so we can ignore this user issue.

The other user we're still trying to get the full log for. Initially, we had discounted hardware as the issue as the user mentioned above had a known good setup, but now we wonder whether it could be because their (integrated) GPU isn't supported in some way. When we send logs we capture device information provided by Unity, perhaps there is something here that gives you a clue?

Battery level   1
Battery status  Full
Operating system    Windows 10 (10.0.19042) 64bit
Operating system family Windows
Processor type  Intel(R) Core(TM) i7-8650U CPU @ 1.90GHz
Processor frequency 2112
Processor count 8
System memory size  8071
Device model    Latitude 7490 (Dell Inc.)
Supports accelerometer  False
Supports gyroscope  False
Supports location service   False
Supports vibration  False
Supports audio  True
Device type Desktop
Graphics memory size    4035
Graphics device name    Intel(R) UHD Graphics 620
Graphics device vendor  Intel
Graphics device ID  22807
Graphics device vendor ID   32902
Graphics device type    Direct3D11
Graphics u v starts at top  True
Graphics device version Direct3D 11.0 [level 11.1]
Graphics shader level   50
Graphics multi threaded True
Rendering threading mode    MultiThreaded
Has hidden surface removal on g p u False
Has dynamic uniform array indexing in fragment shaders  True
Supports shadows    True
Supports raw shadow depth sampling  True
Supports render textures    True
Supports motion vectors True
Supports render to cubemap  True
Supports image effects  True
Supports3 d textures    True
Supports compressed3 d textures True
Supports2 d array textures  True
Supports3 d render textures True
Supports cubemap array textures True
Copy texture support    Basic, Copy3D, DifferentTypes, TextureToRT, RTToTexture
Supports compute shaders    True
Supports geometry shaders   True
Supports tessellation shaders   True
Supports render target array index from vertex shader   True
Supports instancing True
Supports hardware quad topology False
Supports32bits index buffer True
Supports sparse textures    True
Supported render target count   8
Supports separated render targets blend True
Supported random write target count 8
Supports multisampled textures  1
Supports multisampled2 d array textures True
Supports multisample auto resolve   False
Supports texture wrap mirror once   1
Uses reversed z buffer  True
Supports stencil    1
Npot support    Full
Max texture size    16384
Max cubemap size    16384
Max compute buffer inputs vertex    128
Max compute buffer inputs fragment  128
Max compute buffer inputs geometry  128
Max compute buffer inputs domain    128
Max compute buffer inputs hull  128
Max compute buffer inputs compute   32
Max compute work group size 1024
Max compute work group size x   1024
Max compute work group size y   1024
Max compute work group size z   64
Supports async compute  False
Supports gpu recorder   False
Supports graphics fence True
Supports async g p u readback   True
Supports ray tracing    False
Supports set constant buffer    True
Constant buffer offset alignment    256
Min constant buffer offset alignment    False
Has mip max level   True
Supports mip streaming  True
Graphics pixel fillrate -1
Uses load store actions False
Hdr display support flags   Supported, RuntimeSwitchable, AutomaticTonemapping
Supports conservative raster    True
Supports multiview  False
Supports store and resolve action   True
Supports vertex programs    True
Supports g p u fence    False

With regards to your points about disposing of the RemoteRenderingClient, in this users scenario under normal circumstances dispose would not have been called at any point. They started the app and attempted to connect then got this error, no previous sessions had been running.

ChristopherManthei commented 2 years ago

@WikkidEdd the hardware looks fine to me. According to our docs page we require Skylake and newer CPUs on Intel platforms so the i7-8650U used here should be capable of running ARR (it supports hardware h265 and h264 decoding). If not, the connect call would fail with error VideoCodecNotAvailable.

If you are using ARRServiceUnity, I would assume some error caused the program to execute the component Destroy method or Deinitialize was called. I'd suggest adding logging around those functions to make sure these are not executed by accident. We will continue to look through our code to see if there are any other code paths that could potentially dispose the RemoteRenderingClient and invalidate the session object.

ChristopherManthei commented 2 years ago

Hi again @WikkidEdd , with the latest ARR release 1.0.54 we fixed the render code to no longer spam exception in case an invalid session is set to active which should also prevent the screen from going black as a result of throwing in the render loop. We couldn't find a clear cause for the session turning invalid but we did fix an inconsistency in the arrServiceUnity which probably triggered "RRException: Trying to open a session while a session already exists is not supported" and would result in a stopped session remaining the active session in RemoteManagerUnity (see also release anouncement above): "ARRServiceUnity.StopSession will now set the CurrentActiveSession to null upon completion. This way StopSession / ForgetSession are the opposite operations of StartSession / OpenSession as it was originally intended."

We hope that this change will give you better logs the next time the problem appears.

Cheers, Christopher

WikkidEdd commented 2 years ago

Great, we upgraded this afternoon :)

We're also going to improve our logging behaviour so that duplicate log lines are removed so in future we can keep hold of the important logs messages :)

I'll close this issue now as I don't think we'll get any further with it until we have more information.