FNA-XNA / FNA

FNA - Accuracy-focused XNA4 reimplementation for open platforms
https://fna-xna.github.io/
2.56k stars 261 forks source link

Implement VulkanDevice #11

Closed flibitijibibo closed 4 years ago

flibitijibibo commented 8 years ago

The Vulkan 1.0 specification has been released:

https://www.khronos.org/vulkan/

The quick reference manual is here:

https://www.khronos.org/registry/vulkan/specs/1.0/refguide/Vulkan-1.0-web.pdf

Example code can be found here:

https://github.com/SaschaWillems/Vulkan/

This will act as a tracker for a possible alternative to the FNA OpenGLDevice that uses Vulkan for graphics driver interaction. There would be a handful of benefits, including a dramatic reduction in CPU overhead (something we desperately need as a C# project) as well as better use of XNA4's GraphicsDevice render state bindings, but the downside is that it requires higher-spec graphics hardware no matter how fast it ends up being. Additionally, this would mean maintaining two separate devices, which means more regression testing for critical graphics changes. Apple does not have native Vulkan support, but MoltenVK should allow us to use it via Metal, similar to our D3D11 support via ANGLE.

A high level overview of the work needed to get a VulkanDevice:

In theory Vulkan should be more compatible with XNA4 than OpenGL, and we may even be able to use XNA4's own limitations to our advantage when wrangling any possible use cases (thereby eliminating overly generic cases typically handled by drivers and further reducing overhead), but part of having explicit control will mean taking in responsibilities previously handled by driver vendors, and the difficulty of such responsibilities should NOT be underestimated.

Sineaggi commented 8 years ago

Looking at other Vulkan c# binding implementations and comparing them to my own tests, this task isn't as simple as grabbing some OpenGL bindings would be. Most bindings require some form of unsafe, as well as custom marshaling. Any struct that contains another struct is passed via an IntPtr (e.g. createInfop.ApplicationInfo = new IntPtr(&appInfo);) and any utf8 strings need to be converted to and from IntPtrs. Heck, I get crashes going from a 64bit to a 32bit c# runtime.

flibitijibibo commented 8 years ago

That doesn't sound terribly different from the usual, honestly. Going to hazard a guess that people are spending a lot of time wrapping and not a lot of time binding, so lots of C#-itudes are being inserted before direct interop works. For FNA's Vulkan it's almost certainly going to be all raw pointers with stuff malloc()d by hand unless it can absolutely be relied on in C# (which most of it won't).

flibitijibibo commented 7 years ago

With ARB_gl_spirv now on the table, I now recommend starting with MojoShader first. Get SPIR-V output working with the ModernGLDevice, then do VulkanDevice afterward.

flibitijibibo commented 7 years ago

Work on a SPIR-V emitter for MojoShader with ARB_gl_spirv support is in my repository's spirv branch:

https://github.com/flibitijibibo/MojoShader/tree/spirv

Still much to do, so if you're interested in this and want to look it over, please do!

flibitijibibo commented 6 years ago

SDL 2.0.6 has been released, which includes work to simplify Vulkan context creation:

https://discourse.libsdl.org/t/sdl-2-0-6-released/23109

This cuts out a lot of busy work for the VulkanDevice, and SDL_Vulkan_LoadLibrary() should help us detect Vulkan support before the window is made (so we can pick SDL_WINDOW_OPENGL or SDL_WINDOW_VULKAN for the window flags).

flibitijibibo commented 6 years ago

MoltenVK has been released as FOSS, so this issue is now applicable to macOS and iOS/tvOS:

https://www.khronos.org/news/press/vulkan-applications-enabled-on-apple-platforms

https://hg.libsdl.org/SDL/rev/d97ab6d12404

flibitijibibo commented 6 years ago

I've started a bounty system for some of my projects, and a SPIR-V emitter for MojoShader is one of them. Check it out if you think you can write it:

https://github.com/flibitijibibo/flibitBounties/issues/1

TheSpydog commented 5 years ago

We may be able to bypass the SPIR-V emitter entirely for Apple platforms since MoltenVK just converts it to MSL anyway. If we use the existing Metal emitter, we can skip the expensive SPIR-V -> MSL conversion and just pass the output to vkCreateShaderModule with an MVKMSLMagicNumber, as described here:

https://github.com/KhronosGroup/MoltenVK/blob/master/Docs/MoltenVK_Runtime_UserGuide.md#metal-shading-language-shaders

flibitijibibo commented 4 years ago

MojoShader now supports SPIR-V shaders, and supports paths that are friendly to both ARB_gl_spirv and Vulkan. The remaining work should now be mostly on the C# side, unless the Effects work ends up going into a mojoshader_vulkan.c file.

flibitijibibo commented 4 years ago

FNA now has a MetalDevice! While it's not nearly as explicit as Vulkan, it may be an alternative to ModernGLDevice as a starting point for the VulkanDevice.

oroechimaru commented 4 years ago

How far along is vulkan development? Do you have to re-code all your non-vulkan stuff to vulkan or does it handle it? =) =)

TheSpydog commented 4 years ago

Aside from my short-lived (and functionally useless) vulkan branch, I don't think there's been any development on VulkanDevice itself yet. That said, we do sort of support Vulkan via ANGLE, which is how FNA is able to run on Google Stadia. You can read the checklist in the OP for a better sense of what work is remaining to support Vulkan properly. That said, the OpenGL backend isn't going anywhere, even once Vulkan is supported. So it's not a rewrite, it's just adding on to the existing codebase.

flibitijibibo commented 4 years ago

We're now committing to FNA3D for future graphics work, see the issue tracker there!