diff --git a/src/xrt/compositor/client/comp_vk_client.c b/src/xrt/compositor/client/comp_vk_client.c
index ceb6a2228..35b7a2613 100644
--- a/src/xrt/compositor/client/comp_vk_client.c
+++ b/src/xrt/compositor/client/comp_vk_client.c
@@ -407,26 +407,49 @@ client_vk_compositor_layer_commit(struct xrt_compositor *xc, int64_t frame_id, x
 
 	struct client_vk_compositor *c = client_vk_compositor(xc);
 
-	//! @todo We should be creating the handle ourselves in the future.
-	assert(!xrt_graphics_sync_handle_is_valid(sync_handle));
+	// Got a ready made handle, assume it's in the command stream and call commit directly.
+	if (xrt_graphics_sync_handle_is_valid(sync_handle)) {
+		// Commit consumes the sync_handle.
+		return xrt_comp_layer_commit(&c->xcn->base, frame_id, sync_handle);
+	}
+
+	struct vk_bundle *vk = &c->vk;
+	VkResult ret = VK_SUCCESS;
+
+#if defined(XRT_GRAPHICS_SYNC_HANDLE_IS_FD)
+	// Using sync fds currently to match OpenGL extension.
+	bool sync_fence = vk->external.fence_sync_fd;
+#elif defined(XRT_GRAPHICS_SYNC_HANDLE_IS_WIN32_HANDLE)
+	bool sync_fence = vk->external.fence_win32_handle;
+#else
+#error "Need port to export fence sync handles"
+#endif
 
 	/*!
-	 * @!todo This is a temporary solution, the first step in getting proper
-	 * synchronization on Vulkan. The second is to create a fence and share
-	 * it similarly to what the EGL client code does. Even with a fence it
-	 * won't help that much as the multi-compositor waits on the fence in
-	 * commit before proceeding. To fix that a thread will be added in the
-	 * multi-compositor to wait on the fence and allow commit to return.
-	 * Better still is using Semaphores for it all.
+	 * @todo Even with a fence it won't help that much as the multi-
+	 * compositor waits on the fence in commit before proceeding. To fix
+	 * that a thread will be added in the multi-compositor to wait on the
+	 * fence and allow commit to return. Better still is using timeline
+	 * semaphores for it all.
 	 */
-	{
+	if (sync_fence) {
+		COMP_TRACE_IDENT(create_and_submit_fence);
+
+		ret = vk_create_and_submit_fence_native(vk, &sync_handle);
+		if (ret != VK_SUCCESS) {
+			// This is really bad, log again.
+			U_LOG_E("Could not create and submit a native fence!");
+			return XRT_ERROR_VULKAN;
+		}
+	} else {
 		COMP_TRACE_IDENT(device_wait_idle);
 
-		struct vk_bundle *vk = &c->vk;
+		// Last course of action fallback.
 		vk->vkDeviceWaitIdle(vk->device);
 	}
 
-	return xrt_comp_layer_commit(&c->xcn->base, frame_id, XRT_GRAPHICS_SYNC_HANDLE_INVALID);
+	// Commit consumes the sync_handle.
+	return xrt_comp_layer_commit(&c->xcn->base, frame_id, sync_handle);
 }
 
 static xrt_result_t