<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/from-browsers-to-better-drivers-fixing-zink-synchronization-the-hard-way-9gi1qhj4l" -->

---
title: From browsers to better drivers: Fixing Zink...
description: Faith Ekstrand at Collabora details the synchronization bugs that had to be fixed in Zink (the OpenGL-over-Vulkan layer in Mesa) before Zink+NVK could become...
canonical: https://daily.dev/posts/from-browsers-to-better-drivers-fixing-zink-synchronization-the-hard-way-9gi1qhj4l
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: From browsers to better drivers: Fixing Zink synchronization the hard way | daily.dev
og:description: Faith Ekstrand at Collabora details the synchronization bugs that had to be fixed in Zink (the OpenGL-over-Vulkan layer in Mesa) before Zink+NVK could become...
og:url: https://daily.dev/posts/from-browsers-to-better-drivers-fixing-zink-synchronization-the-hard-way-9gi1qhj4l
og:image: https://api.daily.dev/og/posts/9gI1qHJ4l.png
og:image:alt: From browsers to better drivers: Fixing Zink synchronization the hard way
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# From browsers to better drivers: Fixing Zink synchronization the hard way

**[Collabora Blog](https://daily.dev/sources/collabora)** · 14 min read · 0 upvotes · 0 comments

## Summary

Faith Ekstrand at Collabora details the synchronization bugs that had to be fixed in Zink (the OpenGL-over-Vulkan layer in Mesa) before Zink+NVK could become the default OpenGL implementation for Nouveau. Five distinct bugs are covered: (1) Zink incorrectly treating imported VkSemaphores as one-shot, breaking WebGL/WebGPU in Chromium; (2) swapped width/height in damage rectangle code causing Firefox rendering corruption; (3) Zink queuing Wayland presents to a background thread, violating the rule that all wl_surface protocol messages must happen inside eglSwapBuffers/vkQueuePresent; (4) Kopper caching VkSurfaces against proxy-wrapper wl_surface objects instead of the originals, causing duplicate surface creation; and (5) Zink failing to re-detect queue family ownership transfers for dma-buf images used more than once, causing unsynchronized rendering in X11/Glamor. Each bug is traced through real debugging sessions with Chromium and Firefox acting as inadvertent stress tests for Zink's EGL implementation.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://www.collabora.com/news-and-blog/blog/2025/10/27/from-browsers-to-better-drivers-fixing-synchronization-in-zink>

## Questions this post answers

### Why does Zink break the binary Vulkan semaphore rule when doing GL-Vulkan interop with imported semaphores?

Zink was treating all synchronization primitives as one-shot and discarding the VkSemaphore immediately after it was signaled. When a VkSemaphore is imported via GL_EXT_semaphore, it must be persistent — the same semaphore can be signaled and waited on multiple times. Zink's incorrect assumption caused it to sometimes fail to signal semaphores, leaving vkQueueSubmit waiting forever for a binary semaphore that would never materialize.

_Developers working on GL-Vulkan interop layers can track Mesa fixes like this on daily.dev before they hit a stable release._

### Why is it forbidden to queue Wayland presents to a background thread in a Vulkan or EGL driver?

All Wayland protocol messages related to a present — attaching a buffer, setting sync points, committing — must happen atomically inside eglSwapBuffers() or vkQueuePresent(). If a driver queues the present to a background thread, another thread in the application can issue its own wl_surface.commit() between the driver's set_acquire_point and its wl_surface.attach, producing a protocol error because the compositor sees sync points set with no buffer attached.

_Graphics engineers navigating Wayland WSI threading constraints find relevant Mesa patches and discussions on daily.dev._

### How does Zink implement implicit synchronization for dma-buf images when running inside an X11 server with Glamor?

Zink uses dma-buf sync file import/export ioctls to read the current write/read fences from a dma-buf as a sync file and to set the write fence after rendering. Combined with Vulkan's sync file import/export, this lets Zink perform queue family ownership transfers from VK_QUEUE_FAMILY_EXTERNAL to the 3D queue before rendering and back afterward. A bug caused Zink to skip these transfers on the second and subsequent uses of the same dma-buf image, which was only caught in X11 because Wayland compositors re-import images every frame.

_Developers debugging implicit sync issues in Linux graphics drivers can follow Mesa development threads on daily.dev._

## Similar posts on daily.dev

- [Imagination's Open-Source PowerVR Vulkan Driver Now Plays Nicely With Zink OpenGL](https://daily.dev/posts/imagination-s-open-source-powervr-vulkan-driver-now-plays-nicely-with-zink-opengl-neig2zhea) · Phoronix · 0 upvotes · 0 comments
- [Proposed Wine Code Uses Zink For OpenGL-On-Vulkan By Default](https://daily.dev/posts/proposed-wine-code-uses-zink-for-opengl-on-vulkan-by-default-blylzehps) · Phoronix · 0 upvotes · 0 comments
- [Linux gaming's next leap isn't more FPS, it's a working Wayland overlay](https://daily.dev/posts/linux-gaming-s-next-leap-isn-t-more-fps-it-s-a-working-wayland-overlay-1ff6i0kv1) · XDA Developers · 0 upvotes · 0 comments
- [Investigating Linux graphics](https://daily.dev/posts/investigating-linux-graphics-pt8vvc5hu) · Lobsters · 0 upvotes · 0 comments

---

Tags: [#linux](https://daily.dev/tags/linux), [#vulkan](https://daily.dev/tags/vulkan), [#mesa](https://daily.dev/tags/mesa)

[View this post on daily.dev](https://daily.dev/posts/from-browsers-to-better-drivers-fixing-zink-synchronization-the-hard-way-9gi1qhj4l)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"From browsers to better drivers: Fixing Zink synchronization the hard way","url":"https://daily.dev/posts/from-browsers-to-better-drivers-fixing-zink-synchronization-the-hard-way-9gi1qhj4l","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/from-browsers-to-better-drivers-fixing-zink-synchronization-the-hard-way-9gi1qhj4l"},"datePublished":"2026-08-11T08:57:26.219Z","dateModified":"2026-08-11T09:44:35.159Z","description":"Faith Ekstrand at Collabora details the synchronization bugs that had to be fixed in Zink (the OpenGL-over-Vulkan layer in Mesa) before Zink+NVK could become...","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/8a77aec46cb2eea2af20cfe34a6f53cf?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/8a77aec46cb2eea2af20cfe34a6f53cf?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"Collabora Blog","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"Collabora Blog","logo":"https://media.daily.dev/image/upload/s--ZGZ0FjqS--/f_auto,q_auto/v1786438306/logos/collabora?_a=BAMAMicg0","url":"https://daily.dev/sources/collabora"},"commentCount":0,"discussionUrl":"https://daily.dev/posts/from-browsers-to-better-drivers-fixing-zink-synchronization-the-hard-way-9gi1qhj4l","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":0},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"keywords":"linux,vulkan,mesa","timeRequired":"PT14M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"Collabora Blog","item":"https://daily.dev/sources/collabora"},{"@type":"ListItem","position":3,"name":"From browsers to better drivers: Fixing Zink synchronization the hard way"}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/from-browsers-to-better-drivers-fixing-zink-synchronization-the-hard-way-9gi1qhj4l#faq","mainEntity":[{"@type":"Question","name":"Why does Zink break the binary Vulkan semaphore rule when doing GL-Vulkan interop with imported semaphores?","acceptedAnswer":{"@type":"Answer","text":"Zink was treating all synchronization primitives as one-shot and discarding the VkSemaphore immediately after it was signaled. When a VkSemaphore is imported via GL_EXT_semaphore, it must be persistent — the same semaphore can be signaled and waited on multiple times. Zink's incorrect assumption caused it to sometimes fail to signal semaphores, leaving vkQueueSubmit waiting forever for a binary semaphore that would never materialize. Developers working on GL-Vulkan interop layers can track Mesa fixes like this on daily.dev before they hit a stable release."}},{"@type":"Question","name":"Why is it forbidden to queue Wayland presents to a background thread in a Vulkan or EGL driver?","acceptedAnswer":{"@type":"Answer","text":"All Wayland protocol messages related to a present — attaching a buffer, setting sync points, committing — must happen atomically inside eglSwapBuffers() or vkQueuePresent(). If a driver queues the present to a background thread, another thread in the application can issue its own wl_surface.commit() between the driver's set_acquire_point and its wl_surface.attach, producing a protocol error because the compositor sees sync points set with no buffer attached. Graphics engineers navigating Wayland WSI threading constraints find relevant Mesa patches and discussions on daily.dev."}},{"@type":"Question","name":"How does Zink implement implicit synchronization for dma-buf images when running inside an X11 server with Glamor?","acceptedAnswer":{"@type":"Answer","text":"Zink uses dma-buf sync file import/export ioctls to read the current write/read fences from a dma-buf as a sync file and to set the write fence after rendering. Combined with Vulkan's sync file import/export, this lets Zink perform queue family ownership transfers from VK_QUEUE_FAMILY_EXTERNAL to the 3D queue before rendering and back afterward. A bug caused Zink to skip these transfers on the second and subsequent uses of the same dma-buf image, which was only caught in X11 because Wayland compositors re-import images every frame. Developers debugging implicit sync issues in Linux graphics drivers can follow Mesa development threads on daily.dev."}}]}
```

