Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UsdzExport doesn't work in Build when using IL2CPP, causes Exception (FTV-248) #100

Closed
hybridherbst opened this issue Jun 25, 2019 · 24 comments
Assignees
Labels

Comments

@hybridherbst
Copy link
Contributor

When scripting backend is set to Mono, I can export USDZ fine from a Windows Desktop build (haven't verified completeness yet, but I do get an USDZ file with geometry in it).

When the scripting backend is set to IL2CPP instead, calling ExportUsdz results in exceptions:

Registering plugins: D:/git/schreibkugel/development/Builds/usdzTest/WritingBall_Data/Plugins/share/
UnityEngine.Logger:LogFormat(LogType, String, Object[])
UnityEngine.Debug:LogFormat(String, Object[])
Unity.Formats.USD.InitUsd:Initialize()
Unity.Formats.USD.UsdzExporter:ExportUsdz(String, GameObject)
RuntimeExport:Update()
 
(Filename: C:\buildslave\unity\build\Runtime/Export/Debug/Debug.bindings.h Line: 48)

NotSupportedException: To marshal a managed method, please add an attribute named 'MonoPInvokeCallback' to the method definition. The method we're attempting to marshal is: pxr.UsdCsPINVOKE+SWIGExceptionHelper::SetPendingApplicationException
  at pxr.UsdCsPINVOKE+SWIGExceptionHelper..cctor () [0x00000] in <00000000000000000000000000000000>:0 
  at pxr.UsdCsPINVOKE..cctor () [0x00000] in <00000000000000000000000000000000>:0 
  at pxr.PlugRegistry.GetInstance () [0x00000] in <00000000000000000000000000000000>:0 
  at Unity.Formats.USD.InitUsd.Initialize () [0x00000] in <00000000000000000000000000000000>:0 
  at Unity.Formats.USD.UsdzExporter.ExportUsdz (System.String usdzFilePath, UnityEngine.GameObject root) [0x00000] in <00000000000000000000000000000000>:0 
  at RuntimeExport.Update () [0x00000] in <00000000000000000000000000000000>:0 
Rethrow as TypeInitializationException: The type initializer for 'pxr.UsdCsPINVOKE.SWIGExceptionHelper' threw an exception.
  at pxr.UsdCsPINVOKE..cctor () [0x00000] in <00000000000000000000000000000000>:0 
  at pxr.PlugRegistry.GetInstance () [0x00000] in <00000000000000000000000000000000>:0 
  at Unity.Formats.USD.InitUsd.Initialize () [0x00000] in <00000000000000000000000000000000>:0 
  at Unity.Formats.USD.UsdzExporter.ExportUsdz (System.String usdzFilePath, UnityEngine.GameObject root) [0x00000] in <00000000000000000000000000000000>:0 
  at RuntimeExport.Update () [0x00000] in <00000000000000000000000000000000>:0 
Rethrow as TypeInitializationException: The type initializer for 'pxr.UsdCsPINVOKE' threw an exception.
  at pxr.PlugRegistry.GetInstance () [0x00000] in <00000000000000000000000000000000>:0 
  at Unity.Formats.USD.InitUsd.Initialize () [0x00000] in <00000000000000000000000000000000>:0 
  at Unity.Formats.USD.UsdzExporter.ExportUsdz (System.String usdzFilePath, UnityEngine.GameObject root) [0x00000] in <00000000000000000000000000000000>:0 
  at RuntimeExport.Update () [0x00000] in <00000000000000000000000000000000>:0 
UnityEngine.Logger:LogException(Exception, Object)
UnityEngine.Debug:LogException(Exception)
Unity.Formats.USD.InitUsd:Initialize()
Unity.Formats.USD.UsdzExporter:ExportUsdz(String, GameObject)
RuntimeExport:Update()
 
(Filename: currently not available on il2cpp Line: -1)

ApplicationException: Failed to create: C:\Users\felix\AppData\Local\Temp\zc0u9qvy.z7q\test.usdc
  at USD.NET.Scene.Create (System.String filePath) [0x00000] in <00000000000000000000000000000000>:0 
  at Unity.Formats.USD.UsdzExporter.ExportUsdz (System.String usdzFilePath, UnityEngine.GameObject root) [0x00000] in <00000000000000000000000000000000>:0 
  at RuntimeExport.Update () [0x00000] in <00000000000000000000000000000000>:0 
@lucillecaillaud
Copy link
Contributor

Hi soraryu! I tried to reproduce the issue but I am not able to do so.

I simply changed the "scripting backend" in the players settings to IL2CPP, then do a Usdz export and it worked perfectly with no error.

I'm probably missing a step, would you mind to give me more precise steps to reproduce?
Thank you 🙂

@hybridherbst
Copy link
Contributor Author

Have you tested from an actual Desktop build? Both work fine from Editor.

@hybridherbst
Copy link
Contributor Author

hybridherbst commented Jul 8, 2019

@lucillecaillaud Just tried again, same issue. Here is a project reproducing it. Just build one executable with Mono and one with IL2CPP and take a look at the output log (in AppData\LocalLow\DefaultCompany\USDZ-Repro)
USDZ-IL2CPP-Repro.zip

@lucillecaillaud
Copy link
Contributor

Thanks for the precision, I was able to reproduce the issue.
I took a look at the error, it's definitely not my comfort/knowledge zone but we'll keep track of the issue for further improvement.

@mfe mfe changed the title UsdzExport doesn't work in Build when using IL2CPP, causes Exception UsdzExport doesn't work in Build when using IL2CPP, causes Exception (FTV-248) Jul 9, 2019
@mfe mfe added the bug label Jul 9, 2019
@hybridherbst
Copy link
Contributor Author

Bug still exists in latest 2019.2.0b9, just tried because there were some IL2CPP fixes in the changelog but seems they are not related to this bug.

@lucillecaillaud
Copy link
Contributor

Yes, I think it's more a problem on the binding side (from the C++ USD API to C#).

@jcowles
Copy link
Contributor

jcowles commented Jul 17, 2019

Yeah, seems like there are two issues -- one is the Swig callback, which must be specially tagged for IL2CPP (the error reported above) and the other is the code generator that emits functions/MSIL on demand.

The Swig fix /sounds/ easy, though I haven't looked at it, but the MSIL bit will come with a major performance hit, so we will need to special case it for IL2CPP.

@jcowles
Copy link
Contributor

jcowles commented Jul 22, 2019

Another wrinkle here is that the Swig generated code lives in a .NET project which does not reference the Unity run-time, which means adding the special mono tag to that code is not immediately possible...

@hybridherbst
Copy link
Contributor Author

hybridherbst commented Oct 10, 2019

Any news on this? I'm still waiting for this to be able to use it from WebGL builds.

@lucillecaillaud
Copy link
Contributor

Hi soraryu, no news for that. It is in our scope, but unfortunately I can't provide you any ETA for now. Thanks for your patience and follow up.

@hybridherbst
Copy link
Contributor Author

I'd like to bump this up again. Is there anything I can do to speed things up? I'm still blocked on projects that would hugely benefit if this was able to build with Il2CPP and thus to WebGL.
@lucillecaillaud @jcowles

@TautvydasZilys
Copy link

TautvydasZilys commented Feb 21, 2020

which means adding the special mono tag to that code is not immediately possible...

You don't need to reference Unity code to fix this. Just create a private class with the same name in your assembly:

class MonoPInvokeCallbackAttribute : Attribute
{
}

@jcowles jcowles self-assigned this Apr 4, 2020
@jcowles
Copy link
Contributor

jcowles commented Apr 4, 2020

Reviving this -- going to take another crack at it and try Tautvydas' suggestion

@jcowles
Copy link
Contributor

jcowles commented Apr 4, 2020

Looks like this solution does indeed work(!) -- the next challenge is getting SWIG to generate these attributes, rather than post-processing the generated code... message sent to the swig user group to see if they have any suggestions.

@jcowles
Copy link
Contributor

jcowles commented Apr 4, 2020

Ok, I've now also re-written the fast-path IL Emit code to optionally use dynamic/late binding (slow path) when IL2CPP is enabled.

The next-next problem is that delegate instance methods are not supported, which are used by the USD diagnostic delegate to report errors from C++ up to C#... but perhaps in this case, we can let the USD fallback diagnostic delegate run and hope that it ends up in the device log (this is mostly a feature to get errors to show up in the editor log, which should still work when running in-editor).

NotSupportedException: IL2CPP does not support marshaling delegates that point to instance methods to native code. The method we're attempting to marshal is: pxr.TaskCallback::SwigDirectorRun
  at pxr.UsdCsPINVOKE.TaskCallback_director_connect (System.Runtime.InteropServices.HandleRef jarg1, pxr.TaskCallback+SwigDelegateTaskCallback_0 delegate0) [0x00000] in <00000000000000000000000000000000>:0 
  at pxr.TaskCallback.SwigDirectorConnect () [0x00000] in <00000000000000000000000000000000>:0 
  at USD.NET.BackgroundExecutor.RunReaderLoop () [0x00000] in <00000000000000000000000000000000>:0 
  at System.Action.Invoke () [0x00000] in <00000000000000000000000000000000>:0 
  at System.Runtime.Serialization.DeserializationEventHandler.Invoke (System.Object sender) [0x00000] in <00000000000000000000000000000000>:0 
  at System.Threading.ExecutionContext.RunInternal (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state, System.Boolean preserveSyncCtx) [0x00000] in <00000000000000000000000000000000>:0 
  at System.Threading.ExecutionContext.Run (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state) [0x00000] in <00000000000000000000000000000000>:0 
  at System.Action.Invoke () [0x00000] in <00000000000000000000000000000000>:0 
UnityEngine.Logger:LogException(Exception, Object)
UnityEngine.Debug:LogException(Exception)
System.Action`2:Invoke(T1, T2)

@jcowles
Copy link
Contributor

jcowles commented Apr 4, 2020

Annnnd the next-next-next bug is that IL2CPP/AOT only emits functions which are directly called via code, so we need to figure out how to hint to the compiler that the functions we only call via reflection should still be emitted for compilation.

@jcowles
Copy link
Contributor

jcowles commented Apr 4, 2020

Looks like the [Preserve] attribute can be used to avoid this, but similar to the MonoPInvokeCallback attribute, we will need to figure out how to get SWIG to generate this.

This looks relevant (search for csattributes):
http://www.swig.org/Doc4.0/CSharp.html

@jcowles
Copy link
Contributor

jcowles commented Apr 4, 2020

Ok, I got it running with no errors!

Getting Swig to generate these two attributes and verifying what happens with USD errors is the remaining work to get my change ready to actually commit.

@jcowles jcowles closed this as completed Apr 5, 2020
@jcowles jcowles reopened this Apr 5, 2020
@jcowles
Copy link
Contributor

jcowles commented Apr 5, 2020

Without the DiagnosticDelegate, no logging output from USD goes into the Unity player log, which is unfortunate and will make debugging USD issues extremely hard... seems like we should find a way of supporting logging.

@jcowles
Copy link
Contributor

jcowles commented Apr 5, 2020

Ok, I rewrote the diagnostic delegate as a single static function/callback, rather than the fancy swig inheritance/director thing. Seems to work!

I also got swig to emit the [preserve] attributes.

Looks like the last issue is to get swig to emit the [MonoPInvokeCallback] for exceptions.

@jcowles
Copy link
Contributor

jcowles commented Apr 5, 2020

Turns out we must also emit [Preserve] attributes for all USD types, since they are dynamically allocated at run-time. I think this is still doable in a generic way.

@jcowles
Copy link
Contributor

jcowles commented Apr 23, 2020

Ok, IL2CPP support should be working now on all supported platforms, at least in the dev branch. This should also land in the next USD Unity SDK release, which should also be soon.

@jcowles jcowles closed this as completed Apr 23, 2020
@tufeixp
Copy link

tufeixp commented May 15, 2020

I'm using the 1.0.3-preview.2 downloaded inside the package manager, still get this error when build and run with il2cpp. Do we have il2cpp support for this version? I also tried to build with sdk dev + usd source code, but it failed when build the UsdCs.dll. Would you please send me a dev built binary then I can make it just run with il2cpp runtime build?

NotSupportedException: To marshal a managed method, please add an attribute named 'MonoPInvokeCallback' to the method definition. The method we're attempting to marshal is: pxr.UsdCsPINVOKE+SWIGExceptionHelper::SetPendingApplicationException
at pxr.UsdCsPINVOKE+SWIGExceptionHelper..cctor () [0x00000] in <00000000000000000000000000000000>:0
at pxr.UsdCsPINVOKE..cctor () [0x00000] in <00000000000000000000000000000000>:0
at pxr.PlugRegistry.GetInstance () [0x00000] in <00000000000000000000000000000000>:0
at Unity.Formats.USD.InitUsd.Initialize () [0x00000] in <00000000000000000000000000000000>:0
at Unity.Formats.USD.Examples.HelloUsdExample.Start () [0x00000] in <00000000000000000000000000000000>:0
Rethrow as TypeInitializationException: The type initializer for 'pxr.UsdCsPINVOKE.SWIGExceptionHelper' threw an exception.
at pxr.UsdCsPINVOKE..cctor () [0x00000] in <00000000000000000000000000000000>:0
at pxr.PlugRegistry.GetInstance () [0x00000] in <00000000000000000000000000000000>:0
at Unity.Formats.USD.InitUsd.Initialize () [0x00000] in <00000000000000000000000000000000>:0
at Unity.Formats.USD.Examples.HelloUsdExample.Start () [0x00000] in <00000000000000000000000000000000>:0
Rethrow as TypeInitializationException: The type initializer for 'pxr.UsdCsPINVOKE' threw an exception.
at pxr.PlugRegistry.GetInstance () [0x00000] in <00000000000000000000000000000000>:0
at Unity.Formats.USD.InitUsd.Initialize () [0x00000] in <00000000000000000000000000000000>:0
at Unity.Formats.USD.Examples.HelloUsdExample.Start () [0x00000] in <00000000000000000000000000000000>:0
UnityEngine.Logger:LogException(Exception, Object)
UnityEngine.Debug:LogException(Exception)
Unity.Formats.USD.InitUsd:Initialize()
Unity.Formats.USD.Examples.HelloUsdExample:Start()

(Filename: currently not available on il2cpp Line: -1)

ApplicationException: Failed to create: D:/work/usd/buildIl2cpp/usd_Data\sceneFile.usda
at USD.NET.Scene.Create (System.String filePath) [0x00000] in <00000000000000000000000000000000>:0
at Unity.Formats.USD.Examples.HelloUsdExample.Test () [0x00000] in <00000000000000000000000000000000>:0

(Filename: currently not available on il2cpp Line: -1)

@jcowles
Copy link
Contributor

jcowles commented May 15, 2020

IL2CPP fix has not been released yet, it is only working in the current dev branch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants