Vulkan Development

For those who are interested here is a branch that includes basic Vulkan support missing many features and clearly a WIP. But feel free to play, extend, submit, etc.

https://gitlab.kitware.com/ken-martin/vtk/-/tree/vulkan/Rendering/Vulkan

and the readme.md https://gitlab.kitware.com/ken-martin/vtk/-/blob/vulkan/Rendering/Vulkan/README.md which talks some about the design, features, etc.

9 Likes

Awesome work!
I am not familiar with Vulkan yet but this is very exciting.

This is a very good direction !

The post is old, but the vulkan branch seems to be updated recently.
The opengl implementation used in vtk is very old, some GPU drivers (like AMD) are no more supporting such older API and I experiment drivers crash when using vtk with glx on some code using AMD (but not NVIDIA). The vulkan support could be a solution !

I am not able to clone the repository to test your branch on my work (Permission denied, probably due to vtk private account).

  1. Is it planned to merge the vulkan branch into master ?
  2. if yes, when ?
  3. Is it possible to provide me an access to clone and test your branch on my work ?

Thanks for your great work !

You should be able to clone, I checked the settings and they are public unless I missed something. Maybe somethnig off on the clone command, try https maybe instead of ssh https://gitlab.kitware.com/ken-martin/vtk.git Not sure if anyone else has tried cloning it.

I do plan on merging it to master eventually. Just have been working on other things for a while but I plan to get back to it soon.

Thanks for your reply.
I am now able to clone your repository using https.
Unfortunatly, I am not able to compile your branch “vulkan”. Indeed, I am under Linux Debian 11 and the file “Findglslang.cmake” is missing. So I replaced it with the one added in an other branch of vtk by commit “8325e114ed7d2c06548ece318c63fd9ff0cea4d1” but it seems to be dedicated for windows.

Is your branch can be compiled on linux ? If yes, do you have some tips to provide to me ?

Thanks again for your very helpful help !

@ken-martin I’m having an issue building:

Rendering/Vulkan/vtkVulkanCellToVTKCellMap.h:30:10: fatal error: vtkStateStorage.h: No such file or directory

It looks like vtkStateStorage.h was never committed? I didn’t see anything that would generate it, but I am trying to build on Linux, which I know you said needed some work.

I have a few changes required to build so far (some missing <functional> and <thread> includes in headers).

  1. It looks like vtkStateStorage.h is in VTK::RenderingOpenGL2 which is not a dependency of VTK::RenderingVulkan. Adding the dependency fixes things but… it probably isn’t the right fix.
  2. There are a few places where VK_DYNAMIC_STATE_RANGE_SIZE is used, but this RPCS3 issue indicates it is deprecated in newer vulkan releases and there is a PR with an example of how to fix.

Let me take a look. I thought I moved that into common as I did all my builds with openGL turned off and had to fix a lot of stuff related to that.

:slight_smile: let me fix that

C:\Users\ken.martin\Documents\vtk3\vtk>git status
On branch vulkan
Your branch is ahead of 'gitlab/vulkan' by 1 commit.
  (use "git push" to publish your local commits)

Untracked files:
  (use "git add <file>..." to include in what will be committed)

        Rendering/Core/vtkStateStorage.h

nothing added to commit but untracked files present (use "git add" to track)

OK I rebased on master (and force pushed) and it now compiles for me. I have an old vulkan SDK and the tests are failing so something is off now but maybe you can give it a look.

OK I updated to the Vulkan SDK 1.2, fixed the compile and the tests all work on my system. New version pushed.

1 Like

Thanks! There are still a few issues (missing functional, threads header-includes in places), but I get much further now.

I’ve pushed an MR that gets things building – but not running – on my linux box. The vulkan tests fail in the same place:

110: Test command: /stage/build/vtk/vulkan/bin/vtkRenderingVulkanCxxTests "TestAsyncData" "-D" "/stage/build/vtk/vulkan/ExternalData/Testing" "-T" "/stage/build/vtk/vulkan/Testing/Temporary"
110: Test timeout computed to be: 1500
110: 
110: Loguru caught a signal: SIGSEGV
110: Stack trace:
110: 16            0x40473e /stage/build/vtk/vulkan/bin/vtkRenderingVulkanCxxTests() [0x40473e]
110: 15      0x7fecf8af0082 __libc_start_main + 242
110: 14            0x404bea /stage/build/vtk/vulkan/bin/vtkRenderingVulkanCxxTests() [0x404bea]
110: 13            0x4050d1 /stage/build/vtk/vulkan/bin/vtkRenderingVulkanCxxTests() [0x4050d1]
110: 12      0x7fecf883a50e vtkVulkanRenderWindow::Render() + 38
110: 11      0x7fecf82e142f vtkRenderWindow::Render() + 641
110: 10      0x7fecf5cef43a vtkXRenderWindowInteractor::Initialize() + 1306
110: 9       0x7fecf883a554 vtkVulkanRenderWindow::Start() + 64
110: 8       0x7fecf883423a vtkVulkanWindowNode::TraverseAllPasses() + 42
110: 7       0x7fecf88342ae vtkVulkanWindowNode::Traverse(int) + 52
110: 6       0x7fecf8833d9d vtkVulkanWindowNode::Apply(int, bool) + 121
110: 5       0x7fecf86bb92e vtkViewNode::Apply(int, bool) + 96
110: 4       0x7fecf88340c2 vtkVulkanWindowNode::Build(bool) + 800
110: 3       0x7fecf87f7232 vtkVulkanInstance::CreateDevice(VkSurfaceKHR_T*) + 172
110: 2       0x7fecf87fb7e5 vtkVulkanPhysicalDevice::GetQueueFamily(unsigned int&, unsigned int&, VkSurfaceKHR_T*) + 155
110: 1       0x7fecf84821aa /stage/install/vulkan/1.2.176.1/x86_64/lib/libvulkan.so.1(+0x321aa) [0x7fecf84821aa]
110: 0       0x7fecf8b05860 /lib64/libc.so.6(+0x3c860) [0x7fecf8b05860]
110: (   0.084s) [main thread     ]                       :0     FATL| Signal: SIGSEGV
2/7 Test #110: VTK::RenderingVulkanCxx-TestAsyncData ................***Exception: SegFault  0.34 sec

I assume this is because of windows-specific code in vtkVulkanWindowNode as mentioned in the readme? It looks like I need to write a Rendering/UI/vtkXlibHardwareWindow class? Or would it be better to use the Xcb interface? (It looks like vulkan supports both, as well as wayland – but nvidia’s proprietary drivers don’t look like they support wayland.)

Take a look at vtkVulkanWindowNode.cxx around line 244. Only win32 has been filled in. Need some small bit of boilerplate code for X windows I suspect.

Also see the first couple bullets here under todo. Not a lot required but some linux code needs to be written.

https://gitlab.kitware.com/ken-martin/vtk/-/blob/vulkan/Rendering/Vulkan/README.md

Yup, I will take a stab at it. Thanks.

Well, I’m further… here is a merge request that doesn’t crash but doesn’t look exactly right either.

Here’s what running one of the tests produces:

./bin/vtkRenderingVulkanCxxTests TestAsyncData \
  -D /build/vtk/vulkan/ExternalData/Testing \
  -T /build/vtk/vulkan/Testing/Temporary 

The background is the desktop background… vulkan doesn’t appear to draw a background (and perhaps I requested an X11 visual with transparency when I shouldn’t have?). There’s also no response to mouse/keyboard interaction. But, progress!

Update

Changing the default visual to a depth of 24 (instead of 32) yields a window with a dark blue background. Resizes don’t work (the window changes shape but is simply filled with black – nothing gets rendered to it after the first frame).

1 Like

@ken-martin I’m working through test failures and have a question about RenderingVulkanCxx-TestChangingData. It fails with this error:

vtkRenderingVulkanCxxTests: /stage/source/vtk/vulkan/Common/Core/vtkDataArrayTupleRange_Generic.h:141: vtk::detail::ConstComponentReference<ArrayType, <anonymous> >::operator vtk::detail::ConstComponentReference<ArrayType, <anonymous> >::APIType() const [with ArrayType = vtkDataArray; int TupleSize = 3; vtk::detail::ConstComponentReference<ArrayType, <anonymous> >::APIType = double]: Assertion `"Bad assumption in VTK_ASSUME: " "this->Array->GetNumberOfComponents() == this->NumComps.value"&& c' failed.

while trying to dereference multiple components from an array that appears to have only one. The backtrace (below) indicates that offender is a PointNormalsWorker running on thread 3 (i.e., not the GUI thread). Any idea why a single-component, 64-bit integer array would be used for point normals?

(lldb) bt
* thread #4, name = 'vtkRenderingVul', stop reason = signal SIGABRT
  * frame #0: 0x00007ffff7e0b7d5 libc.so.6`raise + 325
    frame #1: 0x00007ffff7df4895 libc.so.6`abort + 295
    frame #2: 0x00007ffff7df4769 libc.so.6`.annobin_unwind_resume.c_end.unlikely + 15
    frame #3: 0x00007ffff7e03e86 libc.so.6`__assert_fail + 70
    frame #4: 0x00007ffff7ae594b libvtkRenderingVulkan-9.0.so.1`vtk::detail::ConstComponentReference<vtkDataArray, 3>::operator double(this=0x00007fffea474b60) const at vtkDataArrayTupleRange_Generic.h:141:5
    frame #5: 0x00007ffff7ade1c5 libvtkRenderingVulkan-9.0.so.1`(anonymous namespace)::PointNormalWorker::operator(this=0x00007fffea474c88, pointArray=0x00007fffe0000b60, normalArray=0x00007fffe4000ca0)<vtkDataArray, vtkDataArray>(vtkDataArray *, vtkDataArray *) const at vtkVulkanBufferManager.cxx:427:17
    frame #6: 0x00007ffff7add8bd libvtkRenderingVulkan-9.0.so.1`asyncbuffer(device=0x000000000046e770, da=0x00007fffe0000b60, normals=0x00007fffe4000ca0, buff=0x000000000045b230) at vtkVulkanBufferManager.cxx:462:11
    frame #7: 0x00007ffff7add98b libvtkRenderingVulkan-9.0.so.1`operator(__closure=0x000000000045d450, w=0x00000000006d2db0) at vtkVulkanBufferManager.cxx:509:20
    frame #8: 0x00007ffff7ae14d2 libvtkRenderingVulkan-9.0.so.1`std::__invoke_impl<void, vtkVulkanBufferManager::GetBufferPointsNormals(vtkVulkanBufferManager::BufferRequest, vtkDataArray*, bool)::<lambda(vtkVulkanBufferManager::Worker*)>&, vtkVulkanBufferManager::Worker*>((null)=__invoke_other @ 0x00007fffea474d40, __f=0x000000000045d450, (null)=0x00007fffea474da0) &) at invoke.h:60:36
    frame #9: 0x00007ffff7ae05b1 libvtkRenderingVulkan-9.0.so.1`std::__invoke_r<void, vtkVulkanBufferManager::GetBufferPointsNormals(vtkVulkanBufferManager::BufferRequest, vtkDataArray*, bool)::<lambda(vtkVulkanBufferManager::Worker*)>&, vtkVulkanBufferManager::Worker*>(__fn=0x000000000045d450, (null)=0x00007fffea474da0) &) at invoke.h:153:33
    frame #10: 0x00007ffff7adfeae libvtkRenderingVulkan-9.0.so.1`std::_Function_handler<void(vtkVulkanBufferManager::Worker*), vtkVulkanBufferManager::GetBufferPointsNormals(vtkVulkanBufferManager::BufferRequest, vtkDataArray*, bool)::<lambda(vtkVulkanBufferManager::Worker*)> >::_M_invoke(__functor=0x000000000045d450, __args#0=0x00007fffea474da0) at std_function.h:291:30
    frame #11: 0x00007ffff7aec71b libvtkRenderingVulkan-9.0.so.1`std::function<void (vtkVulkanBufferManager::Worker*)>::operator(this=0x000000000045d450, __args#0=0x00000000006d2db0)(vtkVulkanBufferManager::Worker*) const at std_function.h:622:14
    frame #12: 0x00007ffff7aec696 libvtkRenderingVulkan-9.0.so.1`void std::__invoke_impl<void, std::function<void (vtkVulkanBufferManager::Worker*)>, vtkVulkanBufferManager::Worker*>((null)=__invoke_other @ 0x00007fffea474e00, __f=0x000000000045d450, (null)=0x000000000045d448)>&&, vtkVulkanBufferManager::Worker*&&) at invoke.h:60:36
    frame #13: 0x00007ffff7aec5f7 libvtkRenderingVulkan-9.0.so.1`std::__invoke_result<std::function<void (vtkVulkanBufferManager::Worker*)>, vtkVulkanBufferManager::Worker*>::type std::__invoke<std::function<void (__fn=0x000000000045d450, (null)=0x000000000045d448)>, vtkVulkanBufferManager::Worker*>(std::function<void (vtkVulkanBufferManager::Worker*)>&&, vtkVulkanBufferManager::Worker*&&) at invoke.h:95:40
    frame #14: 0x00007ffff7aec567 libvtkRenderingVulkan-9.0.so.1`void std::thread::_Invoker<std::tuple<std::function<void (vtkVulkanBufferManager::Worker*)>, vtkVulkanBufferManager::Worker*> >::_M_invoke<0ul, 1ul>(this=0x000000000045d448, (null)=_Index_tuple<0, 1> @ 0x00007fffea474e60) at thread:264:26
    frame #15: 0x00007ffff7aec520 libvtkRenderingVulkan-9.0.so.1`std::thread::_Invoker<std::tuple<std::function<void (vtkVulkanBufferManager::Worker*)>, vtkVulkanBufferManager::Worker*> >::operator(this=0x000000000045d448)() at thread:271:20
    frame #16: 0x00007ffff7aec504 libvtkRenderingVulkan-9.0.so.1`std::thread::_State_impl<std::thread::_Invoker<std::tuple<std::function<void (vtkVulkanBufferManager::Worker*)>, vtkVulkanBufferManager::Worker*> > >::_M_run(this=0x000000000045d440) at thread:215:20
    frame #17: 0x00007ffff523e994 libstdc++.so.6`execute_native_thread_routine + 20
    frame #18: 0x00007ffff53ca432 libpthread.so.0`start_thread + 226
    frame #19: 0x00007ffff7ed06d3 libc.so.6`__clone + 67
(lldb) frame select 5
frame #5: 0x00007ffff7ade1c5 libvtkRenderingVulkan-9.0.so.1`(anonymous namespace)::PointNormalWorker::operator(this=0x00007fffea474c88, pointArray=0x00007fffe0000b60, normalArray=0x00007fffe4000ca0)<vtkDataArray, vtkDataArray>(vtkDataArray *, vtkDataArray *) const at vtkVulkanBufferManager.cxx:427:17
   424 	    size_t count = 0;
   425 	    for (const auto& point : pts)
   426 	    {
-> 427 	      (*rptr++) = point[0];
   428 	      (*rptr++) = point[1];
   429 	      (*rptr++) = point[2];
   430 	      auto normal = normals[count];
(lldb) p point.Array->GetClassName()
(const char *) $0 = 0x00007ffff5985511 "vtkTypeInt64Array"
(lldb) p point.Array->GetNumberOfTuples()
(vtkIdType) $1 = 121
(lldb) p point.Array->GetNumberOfComponents()
(int) $2 = 1

Frame 6 at line 462 is already bad, as our arrays should be fine for the normal dispatch code and not hit that line. So yes, something is messed up. When I build the current master I get corrupted memory issues and the tests crash. If I go back to efaa855ad5 the tests work (this is all on windows).

But… my crash on master could have nothing to do with your current issue. I’ll have to dig a bit to see what is up.

But yes, the normal array should never be a single component Int64, that sounds like a vtkIdType cell index array or something.