ogre-next icon indicating copy to clipboard operation
ogre-next copied to clipboard

Use Volk as Vulkan loader

Open mjcarroll opened this issue 1 year ago • 4 comments

I noticed that OGRE is using volk (https://github.com/zeux/volk) as a meta vulkan loader. This would help trim down build dependencies by letting us introspect vulkan entrypoints:

volk is a meta-loader for Vulkan. It allows you to dynamically load entrypoints required to use Vulkan without linking to vulkan-1.dll or statically linking Vulkan loader. Additionally, volk simplifies the use of Vulkan extensions by automatically loading all associated entrypoints. Finally, volk enables loading Vulkan entrypoints directly from the driver which can increase performance by skipping loader dispatch overhead.

Is there any particular reason that ogre-next is not using this?

mjcarroll avatar Aug 17 '22 15:08 mjcarroll

Hi!

The main reason is I just didn't have time to evaluate it and test it.

Volk's (originally) main goal was to get rid of the dispatcher's CPU overhead by using the main GPU.

The Vulkan Loader does a lot things (ensuring layers work, ensuring extensions work, enumerating all available devices); which is very important when doing hooks (RenderDoc, Steam Overlays, debug layers, frame limiters, etc) or selecting GPUs other than the main one.

Layers can be requested by the Application (like debug layers), or force-enabled externally (such as in the case of RenderDoc & Steam Overlays; and debug layers when forced via vkconfig)

It is also the standard-compliant way of using Vulkan; although several Khronos documents do mention volk; and given its popularity it will be remain to be supported.

From what I can read in volk's main page it seems they support all that (except having multiple VkDevice active). OgreNext has its infrastructure open to having multiple devices but it doesn't seem to be in the near future as there is little interest in this.

Ultimately loaders are complex, we even have workarounds for them so ensuring volk has everything we need & want could take time.

Also, since Vulkan support is isolated to RenderSystem_Vulkan.dll/so, IMO directly linking against vulkan1 is a plus; since any linker problem stands out with simply using Dependency Walker or ldd; but it is indeed a problem if statically linking more than one RenderSystem (i.e. optionally supporting GL or Vulkan but statically linking everything; hence if vulkan1.dll isn't present -> app won't even start; instead of falling back to OpenGL)

This would help trim down build dependencies by letting us introspect vulkan entrypoints:

I'm not sure how build dependencies are trimmed down? Volk replaces library linking at ELF level with loading libraries at runtime via dlsym or equivalents. It may make the ELF binary smaller though.

The usage of the phrase introspect vulkan entrypoints confuses me a little, because you can definitely step inside the Vulkan driver with the loader:

1   radv_emit_indirect_draw_packets                 radv_cmd_buffer.c            6464 0x7fff00c7e406 
2   radv_CmdDrawIndexedIndirect                     radv_cmd_buffer.c            7120 0x7fff00c83db8 
3   DispatchCmdDrawIndexedIndirect                  layer_chassis_dispatch.cpp   2940 0x7ffed99fa122 
4   vulkan_layer_chassis::CmdDrawIndexedIndirect    chassis.cpp                  3102 0x7ffed990f6c1 
5   Ogre::VulkanRenderSystem::_render               OgreVulkanRenderSystem.cpp   2064 0x7fff01958245 
6   Ogre::CommandBuffer::execute_drawCallIndexed    OgreCbDrawCall.cpp           82   0x7ffff77d185c 
7   Ogre::CommandBuffer::execute                    OgreCommandBuffer.cpp        108  0x7ffff77d35ad 
8   Ogre::RenderQueue::render                       OgreRenderQueue.cpp          470  0x7ffff75749d4 
9   Ogre::SceneManager::_renderPhase02              OgreSceneManager.cpp         1495 0x7ffff7604297 
10  Ogre::Camera::_renderScenePhase02               OgreCamera.cpp               386  0x7ffff72adf84 
11  Ogre::Viewport::_updateRenderPhase02            OgreViewport.cpp             203  0x7ffff7789573 
12  Ogre::CompositorPassScene::execute              OgreCompositorPassScene.cpp  295  0x7ffff782e131 
13  Ogre::CompositorNode::_update                   OgreCompositorNode.cpp       826  0x7ffff77e8dcd 
14  Ogre::CompositorShadowNode::_update             OgreCompositorShadowNode.cpp 646  0x7ffff77f2aeb 
... <More>                                                                                           

TL;DR

I looked into it but there was a ton of stuff to research and test and I didn't have time or resources to do it. And for the case of Statically Linked Rendersystems, Volk provides additional features (prevent the app from not starting because Vulkan loader isn't present)

darksylinc avatar Aug 17 '22 17:08 darksylinc

Regarding the last point (static linking) it may be worth pointing something out. Having a Vulkan-Capable GPU is not the same as having the loader installed. There's various possibilities:

GPU Loader Status Example
Vulkan Capable Installed Vulkan can be run GeForce 1080 with up to date drivers
Not Vulkan capable Installed Vulkan will be loaded, but 0 devices will be supported; OgreNext fallbacks to OpenGL/D3D11 GeForce 510 (Fermi) with up to date drivers
Vulkan Capable Not installed App or DLL will refuse to load. If built as DLL, OgreNext fallbacks to GL/D3D11 GeForce 980 with ancient drivers (i.e. before 2015)
Not Vulkan capable Not installed App or DLL will refuse to load. If built as DLL, OgreNext fallbacks to GL/D3D11 GeForce 510 (Fermi) with ancient drivers

darksylinc avatar Aug 17 '22 17:08 darksylinc

This was mainly asking out of curiosity. I agree that the APIs are quite complex, and was mainly interested in why the divergence between the two (ogre and ogre-next), when it looked like ogre's implementation was largely inspired by ogre-next.

I'm not sure how build dependencies are trimmed down? Volk replaces library linking at ELF level with loading libraries at runtime via dlsym or equivalents. It may make the ELF binary smaller though.

I'm thinking primarily from a packaging standpoint. Looking across debian, conda, and homebrew, there doesn't seem to be a standard way of getting the Vulkan SDK installed and detected. It's very likely that my understanding of packaging/distribution is a bit weak here though.

I'm running into similar issues with macOS+conda+metal, so it's not something that is necessarily vulkan-specific.

The usage of the phrase introspect vulkan entrypoints confuses me a little, because you can definitely step inside the Vulkan driver with the loader

My understanding was incorrect here then.

mjcarroll avatar Aug 17 '22 18:08 mjcarroll

It seems Godot switched to volk a year ago.

I'm thinking primarily from a packaging standpoint. Looking across debian, conda, and homebrew, there doesn't seem to be a standard way of getting the Vulkan SDK installed and detected. It's very likely that my understanding of packaging/distribution is a bit weak here though.

Well the *.deb package should (must?) depend on libvulkan1 so that the Vulkan loader is installed.

However this won't guarantee Vulkan support. For that, the *.deb package should depend on mesa-vulkan-drivers (which already depends on libvulkan1). The will ensure Vulkan support (as long as the GPU supports it, otherwise that will just install extra libs the system doesn't need).

IMHO it sounds like deb packages should:

  • Depend on libvulkan1
  • Recommend mesa-vulkan-drivers

Or alternatively in the case of Gazebo only recommend mesa-vulkan-drivers; since Gazebo handles the case where RenderSystem_Vulkan.so refused to load.

darksylinc avatar Aug 17 '22 18:08 darksylinc