# Shimizu - The Wayland Protocol, in Zig

**URL:** <https://ziggit.dev/t/shimizu-the-wayland-protocol-in-zig/6246>\
**Category:** Showcase\
**Created:** [October 4, 2024, 5:00am UTC](https://ziggit.dev/t/shimizu-the-wayland-protocol-in-zig/6246 "2024-10-04T05:00:23Z")\
**Posts on this page:** 1\
**Showing post:** 8

<div class="post-metadata">

**Author:** ![geemili](https://ziggit.dev/user_avatar/ziggit.dev/geemili/32/1277_2.png) [@geemili](https://ziggit.dev/u/geemili)\
**Post date:** [October 24, 2024, 4:00am UTC](https://ziggit.dev/t/shimizu-the-wayland-protocol-in-zig/6246/8 "2024-10-24T04:00:56Z")

</div>

[`wl_display` is a specially defined object at id 1](https://wayland.app/protocols/wayland#wl_display). You can acquire a proxy to it using [`shimizu.Connection.getDisplayProxy`](https://git.sr.ht/~geemili/shimizu/tree/dev/item/src/shimizu.zig#L173-178). However, this will not be the `*wl_display` Vulkan is expecting. Any references to Wayland objects in Vulkan will be using `libwayland`, and will require something that links `libwayland`, like [`zig-wayland`](https://github.com/ifreund/zig-wayland) to use.

It is possible to use `shimizu` and Vulkan together. I’ve done it for `seizer`, and you can see [the crappy abstraction I made over it here](https://github.com/leroycep/seizer/blob/dev/src/Graphics/Vulkan.zig). Note that this code has some cruft, and isn’t necessarily the most succinct. Here’s a high level overview of what needs to be done:

1. Connect to the Wayland compositor.
2. Acquire a Vulkan instance. This doesn’t require any knowledge of the Wayland compositor, you are just getting access to the GPU initially.
3. Check if your Wayland compositor exposes a [`zwp_linux_dmabuf_v1` object from the `linux-dmabuf-v1` protocol](https://wayland.app/protocols/linux-dmabuf-v1#zwp_linux_dmabuf_v1). We can make do without this extension, see the addendum for details.
4. Check if your Vulkan device supports [`VK_EXT_external_memory_dma_buf`](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_EXT_external_memory_dma_buf.html). Same as above, we can make do without, see addendum for details.
5. [Create some images to render into](https://github.com/leroycep/seizer/blob/dev/src/Graphics/Vulkan.zig#L934-L1163), making sure they have `dma_buf_bit_ext` set. Normally you are instructed to use the Swapchain extension for this, however, we cannot, as it requires `libwayland`.
6. [Create `wl_buffer` objects using `linux-dmabuf-v1`](https://github.com/leroycep/seizer/blob/6380463176af35fcc3af0908f44589af734acaa1/src/Display/Wayland.zig#L420-L463) by [exporting `dma_buf` handles from Vulkan](https://github.com/leroycep/seizer/blob/6380463176af35fcc3af0908f44589af734acaa1/src/Graphics/Vulkan.zig#L1094-L1131).
7. Tell Vulkan to render into one of images.
8. Attach the associated `wl_buffer` to a `wl_surface` and commit it.
9. Mark the Vulkan image/wl\_buffer as in use until you [receive a release event](https://wayland.app/protocols/wayland#wl_buffer:event:release)
10. Grab another image/wl\_buffer and repeat

And if that giant list didn’t scare you off, congratulations! 🎊 You can now render to Wayland without linking `libwayland`! Unfortunately you will still need to link the appropriate libc.

### Addendum: Rendering Without `linux-dmabuf-v1`

The `linux-dmabuf-v1` protocol lets us tell the Wayland compositor about framebuffers/images that are located on the GPU. However, if that is unsupported, we can fall back to copying images from the GPU into main memory, and then passing that to the Wayland compositor. Here’s what to change:

- Replace getting the `zwp_linux_dmabuf_v1` global with getting `wl_shm`
- Replace `VK_EXT_external_memory_dma_buf` with [`VK_KHR_external_memory_fd`](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_KHR_external_memory_fd.html)
- Replace `dma_buf_bit_ext` with [`opaque_fd_bit`](https://github.com/leroycep/seizer/blob/6380463176af35fcc3af0908f44589af734acaa1/src/Graphics/Vulkan.zig#L944)
- [Create `wl_buffer`s using a shared memory pool](https://github.com/leroycep/seizer/blob/6380463176af35fcc3af0908f44589af734acaa1/src/Display/Wayland.zig#L465-L498)

---

_[View the full topic](https://ziggit.dev/t/shimizu-the-wayland-protocol-in-zig/6246)._
