Repository navigation
Releases: bite-gpui/gpui_interop
Release list
gpui_interop 0.2.0
A bite-gpui 1.25 upgrade. The public wgpu types move to 30, so this is a minor release.
Breaking
- The
wgputypes in the public API —Adapter::wgpu,WgpuSurfaceandWgpuSharedBuffer— are now wgpu 30's. A producer still on wgpu 29 must upgrade before it can hand this crate its device.
Changed
- Built against
bite-gpui1.25.202 (was1.24.401), and the workspace follows the core towgpu30.0.1. - The Bevy producer moved to Bevy 0.20 (
bevy_render0.20), the release that uses wgpu 30, so the example still shares one wgpu with the window renderer. - wgpu 30's
create_texture_from_halnow takes the wrapped texture's initial state; an imported dma-buf image isUNINITIALIZED, as in the core's own importer. - wgpu 30's vertex layout list is a list of
Options; the hand-written pipeline ininterop_wgpufollows it. - The Windows cross-device test no longer needs the
request_windowingworkaround:bite-gpui1.24.401 attached the platform's Direct3D devices lazily inopen_window(bite-gpui/bite-gpui#13), and the test now exercises that path.
Verified
- The full headless suite: 34 tests, including the dma-buf import + pixel read-back, the shared-buffer ring's slow-frame test, the guest worker-thread hand-off, and the input gateway.
- Windows CI runs the hidden-window Direct3D 12 → Direct3D 11 cross-device test.
- Windowed runtime on an Optimus laptop: Bevy 0.20 on the window device (same-device and dma-buf
--transferpaths) at ~38 fps, probe centre pixel non-zero. cargo publish --dry-runwith and withoutgpui,wgpu,guest, against the published 1.25.202 packages.
Install
gpui_interop = { version = "0.2", features = ["gpui", "wgpu"] }Docs: https://docs.rs/gpui_interop/0.2.0
Changelog: https://github.com/bite-gpui/gpui_interop/blob/main/CHANGELOG.md
Full diff: v0.1.3...v0.2.0
gpui_interop 0.1.3
A bite-gpui upgrade. No API changes.
Changed
- Built against
bite-gpui1.24.400 (was1.23.305). No source changes were needed: the offscreen contract,Window::present, the headless renderer factory, the dma-buf explicit-layout guard and the transfer function all keep the shapes this crate already targets. - The 1.24 line carries the upstream platform/engine split and a leaner dependency set, so the lockfile resolves fewer crates.
- CI, the release workflow and
scripts/prepare-publish.pynow pinbite_1.24.400.
Verified
- The full headless suite: 34 tests, including the dma-buf import + pixel read-back, the shared-buffer ring's slow-frame test, the guest worker-thread hand-off, and the input gateway.
cargo publish --dry-runagainst the publishedbite-gpui 1.24.400packages from crates.io, with and without thegpui,wgpu,guestfeature set.
Install
gpui_interop = { version = "0.1.3", features = ["gpui", "wgpu"] }Docs: https://docs.rs/gpui_interop/0.1.3
Changelog: https://github.com/bite-gpui/gpui_interop/blob/main/CHANGELOG.md
Full diff: v0.1.2...v0.1.3
gpui_interop 0.1.2
A producer-side ring that makes slow frames safe. No breaking API changes.
Added
WgpuSharedBufferRing(Linux,wgpufeature): a small ring of exportable frames for a producer that renders continuously.begin()hands out a free slot;submit()exports the frame with its acquire fence.present()returns only a frame whose acquire fence has already signalled, with the fence removed, or repeats the last good frame while a new one is in flight. GPUI's 16 ms poll never drops a slow frame.- Slots are recycled after the consumer's release, with a 250 ms timeout fallback. Frames overtaken by a newer one are dropped, so presentation does not jump backwards.
shared_buffer_ringintegration test (headless Vulkan): a deliberately long frame is never presented with a pending fence.
Why
GPUI's acquire-fence wait is CPU-side, 16 ms, before its draw is submitted — so sharing a device and queue does not help. A frame containing a full-screen overlay (~2.4 ms at 720p, ~5-6 ms at 1080p) can cross that boundary; the surface is then dropped, which shows as a black viewport frame. The ring removes the boundary: it never makes GPUI wait.
Reproduction: lengthening interop_wgpu's submission with extra clear passes produced 67 drops/10 s at 50 passes and 145 drops/10 s at 200. Every handle present() returns is fence-free, which the new regression test asserts.
Install
gpui_interop = { version = "0.1.2", features = ["gpui", "wgpu"] }Docs: https://docs.rs/gpui_interop/0.1.2
Changelog: https://github.com/bite-gpui/gpui_interop/blob/main/CHANGELOG.md
Full diff: v0.1.1...v0.1.2
gpui_interop 0.1.1
A documentation and CI patch. No API changes.
The dma-buf lifetime contract
WgpuSharedBuffer::submit starts the write; it does not wait for it. The consumer samples the buffer later, on its own submission. Reusing the same export for the next frame while GPUI may still sample it causes intermittent black frames.
Documented in the repository README, the wgpu_dmabuf module docs and the crate docs:
- Keep a ring and present one frame behind the one being rendered, or attach
DmaBufHandle::releaseand wait for it before writing a slot again. - A fixed "reuse after N submissions" rule is a heuristic; a deep consumer queue or a coalesced frame can outlast it.
- GPUI polls a surface's acquire fence for 16 ms and drops the surface on timeout, which presents as a black frame. A frame that runs long is safer presented one frame late.
- Same device does not mean same submission: gate on the release, not on device identity.
- Measured cost of a full-screen overlay: ~2.4 ms at 1280x720 with 4x MSAA (~5-6 ms at 1080p) on an Intel HD 520.
Issue #1 has the reproduction, the measurements and the release-semantics answers.
Fixed
- CI and the release workflow check the
bite-gpuicore out beside the workspace, so path dependencies resolve on a clean runner. - The Windows cross-device test is gated on the
gpuifeature.
Install
gpui_interop = "0.1.1"Docs: https://docs.rs/gpui_interop/0.1.1
Full changelog: CHANGELOG.md
Full diff: v0.1.0...v0.1.1