What's the state of the art in Zig ecosystem for Wayland+Vulkan without libc? 2

Taking a closer look at the protocol support, it does say river 0.3.13, so it seems that you’re a few minor versions off

Thank you for pointing that out. Now it runs. And there’s a similar issue to What's the state of the art in Zig ecosystem for Wayland+Vulkan without libc? 2 - #32 by spiffyk but if I make a window full screen it fills with a black color. Also, when resizing a window, it does change the size, but validation layer logs these errors:

error(vk_validation): vkDestroyImage(): cant be called on VkImage 0x1050000000105 that is currently in use by VkCommandBuffer 0x11555840.
The Vulkan spec states: All submitted commands that refer to image, either directly or via a VkImageView, must have completed execution (https://docs.vulkan.org/spec/latest/chapters/resources.html#VUID-vkDestroyImage-image-01000)
error(vk_validation): vkResetCommandPool(): (VkCommandBuffer 0x11555840) is in use.
The Vulkan spec states: All VkCommandBuffer objects allocated from commandPool must not be in the pending state (https://docs.vulkan.org/spec/latest/chapters/cmdbuffers.html#VUID-vkResetCommandPool-commandPool-00040)
error(vk_validation): vkBeginCommandBuffer(): on active VkCommandBuffer 0x11555840 before it has completed. You must check command buffer fence before this call.
The Vulkan spec states: commandBuffer must not be in the recording or pending state (https://docs.vulkan.org/spec/latest/chapters/cmdbuffers.html#VUID-vkBeginCommandBuffer-commandBuffer-00049)
error(vk_validation): vkQueueSubmit(): pSubmits[0].pCommandBuffers[0] VkCommandBuffer 0x11555840 is already in use and is not marked for simultaneous use.
The Vulkan spec states: If any element of the pCommandBuffers member of any element of pSubmits was not recorded with the VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT, it must not be in the pending state (https://docs.vulkan.org/spec/latest/chapters/cmdbuffers.html#VUID-vkQueueSubmit-pCommandBuffers-00071)

Conceptually I love what your saying, and I too would love to adopt this style where possible. If it is possible to simplify things one should do so in general, to me atleast.

Me being a bit naive, do you reckon this loader for any generic library could possibly be automated by e.g. a zig library one could fetch? Or even as a step in build.zig? Or do you foresee this always being a bespoke approach?

I can easily imagine this being something I would like to do. However what you describe sounds like it would either require the technical skill or at the very be somewhat time intensive to implement.

It is in fact a “normal” zig libary, consisting of only two zig files. You can use zig fetch to get it. See here: GitHub - TibboddiT/dyn-loader: dlopen for zig, from static executables and without libc · GitHub.

1 Like

Just want to tie a bow on this, now that I’ve had some time.

I’ve added implicit synchronization as a fallback if the explicit sync setup fails, which means it now works with Nvidia GPUs (at least from my testing).

Thanks to the issues raised in this thread and in the repo, I was able to iron out a lot of little quirks. A couple of the more interesting things I learned along the way:

  1. DRM formats and Vulkan formats are in opposite byte-order on little endian systems. For example, DRM_FORMAT_RGBA8888 -> [4]u8{a, b, g, r}, but VK_FORMAT_R8G8B8A8_UNORM -> [4]u8{r, g, b, a}, unless it’s a _pack format, in which case it’s the opposite VK_FORMAT_A8B8G8R8_UNORM_PACK32 -> [4]u8{r, g, b, a}.
  2. Every compositor seems to send the DMA-BUF feedback events in a slightly different order. You really need to be able to handle these events no matter what order they come in, at least relative to each tranche.

At this point, I have directly tested that this works with all of the following compositors across Arch, Debian, and Fedora:

  • Cosmic
  • Hyprland
  • KWin
  • Labwc
  • Mutter
  • Niri
  • River (classic)
  • Sway

It does not work with Muffin (Cinnamon, Linux Mint), as its Wayland support is currently only experimental and lacks the necessary DMA-BUF extension version (has 3, needs 4).

I will continue to update the repo as I learn, or if any new issues come in. Hopefully others may find this as educational as I have :slightly_smiling_face:

Finally, here’s a little benchmark of the uncapped FPS by number of swap images. Reminder that the only work the GPU is doing is a single, different-per-frame vkCmdClearColorImage(), and I made the window as small as I could, so this is essentially just timing the synchronization overhead (KWin, CachyOS, two frames in flight, ReleaseFast):

Swap Images Approx. FPS
2 23,000
3 40,000
4 42,000

I would have expected 3 images to be faster than 2, but twice as fast was surprising. And just 25 microseconds for all of the syscalls and plumbing was pleasant to see as well.

13 Likes

Nothing vulkan (yet), but this thread got me to play around with wayland again. What I have here
https://codeberg.org/PinieP/walyand-experiment-zig is

  • a code generator Gen.zig that generates zig types from a <wayland-protocol>.xml spec.
  • marshaling/unmarshaling wayland messages in wire_format.zig
  • connection handling/managing, object id reuse, object listeners/callbacks in Conn.zig
  • a small example that does a bit of input handling
2 Likes