Vulkan based 3D rendering in Avalonia iOS app using MoltenVK #18259
llfab
started this conversation in
Show and tell
Replies: 2 comments 6 replies
-
Thanks for the detailed explanation. I think it will be super useful for someone trying to do the same in the future. Some questions...
Thanks! |
Beta Was this translation helpful? Give feedback.
2 replies
-
As I will not be able to release the closed source, I still wanted to provide the main content of the project files. The shared project for both desktop and iOS
The props files just contain the references to the avalonia packages
The Desktop Project
The iOS project
Hope that helps |
Beta Was this translation helpful? Give feedback.
4 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
In this thread I want to explain the important aspects that allowed me to make vulkan based 3D rendering work on iOS devices.
Starting Point
We have a desktop app that targeted Windows and Linux at first. Also we have our own scene graph based 3D renderer that has a vulkan rendering backend only. The integration between the 3D renderer and Avalonia was done through Avalonia's GPU interop API that allows for texture sharing between the Avalonia composition renderer and the 3D renderer even if Avalonia is driven by OpenGL and the 3D renderer is driven by vulkan.
As the GPU interop only supports Windows and Linux and not macOS we have created an additional integration between the 3D renderer and Avalonia that renders into a bitmap that then is put to the screen with
DrawingContext.DrawImage(_texture, sourceRect, targetRect);
. This approach introduces an additional cycle between CPU and GPU which still leads to ~180fps on Apple silicon. So good enough for now.The pure vulkan 3D renderer works once you install VulkanSDK on macOS and LibraryImport from the "libvulkan.dylib" instead of vulkan-1.dll on Windows or similar on Linux.
Hence, as a starting point we had a working solution not only on Window and Linux but also on macOS using MoltenVK.
Goal
As a goal we wanted the very same app work on iOS (iPad and iPhone), even if the existing app layouts would not fit the reduced screens well
The way it worked
Native AOT
We base our apps on our own core libraries that have grown to ~400K LoC. There are some dynamics like
System.Reflection.Emit
being used, hence, I had to find alternatives to support Native AOTAssets / Resources
In many apps we just use project settings like:
which do the job for desktop apps. However, for app bundled apps on iOS you need to package stuff correctly:
<None ... >
because that is not packaged into your app bundle (Warnings during build)PublishFolderType
manuallyNote: if you have a shared (or other transitive) assembly like with the default Avalonia x-plat template (MyProject, MyProject.Desktop, MyProject.iOS), some of the asset features in the project file only work if you multi-target that assembly:
Above
PublishFolderType="Resource"
would e.g. not work if this transitive assembly is not multi-targeted containing the-ios
target.Make MoltenVK part of the app bundle
Obviously, on iOS you cannot install VulkanSDK, hence, you must packages the binaries (and other files) into your app bundle. Note that the packaging for iOS is different than the one for macOS. On macOS you can package the *.dylib files whereas on iOS you should package.(xc)framework bundles.
Most of it is explained here: https://www.khronos.org/blog/developing-with-vulkan-on-apple-ios
I just found it a bit more difficult to translate that into a .NET based application.
Here is what has worked for me:
Therefore, the project settings look as follows:
(Note: vulkan loader and validation layers are not supported for the iOS simulater)
LibraryImport library path (for your own vulkan binding)
Where you would use "vulkan-1.dll" on Windows or "libvulkan.dylib" on macOS, that is different for the app bundled .(xc)framworks. Here, the rpath syntax is used to specify the lib to be loaded. Also you need to account for using vulkan loader or just the pure MoltenVK. Again: there is no vulkan loader on iOS simulator and in your release version you want to use only MoltenVK without the vulkan loader for performance reasons.
These library names have worked for me on the different platforms:
I then use
NativeLibrary.SetDllImportResolver
to set the proper library for the given OS platform.Conclusion
Vulkan on macOS and iOS is supported by Khronos (so it does not only work by accident) and works nicely in an Avalonia app that consists on a single source with stubs for .Destkop and .iOS.
The important tricks are:
Beta Was this translation helpful? Give feedback.
All reactions