diff --git a/lightningbeam-ui/gpu-video-encoder/src/decoder.rs b/lightningbeam-ui/gpu-video-encoder/src/decoder.rs index f53c251..9f64856 100644 --- a/lightningbeam-ui/gpu-video-encoder/src/decoder.rs +++ b/lightningbeam-ui/gpu-video-encoder/src/decoder.rs @@ -195,7 +195,7 @@ impl VaapiDecoder { uv_offset: uv_pl.offset as u64, uv_pitch: uv_pl.pitch as u64, }; - let imported = dmabuf::import_raw(&self.drm, &buf); + let imported = dmabuf::import_raw(&self.drm.device, &self.drm.adapter, &buf); ff::av_frame_free(&mut (drm_f as *mut _)); // the fd was dup'd into Vulkan imported } diff --git a/lightningbeam-ui/gpu-video-encoder/src/dmabuf.rs b/lightningbeam-ui/gpu-video-encoder/src/dmabuf.rs index a6bfc33..a6e1644 100644 --- a/lightningbeam-ui/gpu-video-encoder/src/dmabuf.rs +++ b/lightningbeam-ui/gpu-video-encoder/src/dmabuf.rs @@ -49,10 +49,11 @@ impl ImportedNv12 { } } -/// Convenience: map a freshly-allocated `MappedSurface` and import it. +/// Convenience: map a freshly-allocated `MappedSurface` and import it onto `drm`. pub fn import(drm: &DrmDevice, surf: &MappedSurface) -> Result { import_raw( - drm, + &drm.device, + &drm.adapter, &Nv12DmaBuf { fd: surf.fd, size: surf.size, @@ -67,12 +68,28 @@ pub fn import(drm: &DrmDevice, surf: &MappedSurface) -> Result Result { +/// Import an NV12 DMA-BUF (described by `buf`) as two wgpu plane textures **on `device`**. The raw +/// Vulkan handles are extracted from `device`/`adapter` via `as_hal`, so this works with any +/// DMA-BUF-import-capable wgpu device — the encoder/decoder's own `DrmDevice` *or* the editor's +/// shared device. The fd is duplicated, so the caller keeps ownership of theirs. +pub fn import_raw( + device: &wgpu::Device, + adapter: &wgpu::Adapter, + buf: &Nv12DmaBuf, +) -> Result { + use wgpu_hal::vulkan::Api as Vk; unsafe { - let device = drm.raw_device.clone(); - let instance = &drm.raw_instance; + let hal_device = device + .as_hal::() + .ok_or("device is not Vulkan")?; + let raw_device = hal_device.raw_device().clone(); + let raw_instance = adapter + .as_hal::() + .ok_or("adapter is not Vulkan")? + .shared_instance() + .raw_instance() + .clone(); + let instance = &raw_instance; let dup_fd = libc::dup(buf.fd); if dup_fd < 0 { @@ -103,7 +120,7 @@ pub fn import_raw(drm: &DrmDevice, buf: &Nv12DmaBuf) -> Result Result Result() - .ok_or("device is not Vulkan")?; let wrap = |img: vk::Image, format: wgpu::TextureFormat, w: u32, h: u32| -> wgpu::Texture { // wgpu destroys the image (after wait-idle) when the texture drops; the // captured Arc frees the shared memory once both have run. - let dev = device.clone(); + let dev = raw_device.clone(); let guard = mem_guard.clone(); let cb: wgpu_hal::DropCallback = Box::new(move || { dev.destroy_image(img, None); @@ -170,7 +183,7 @@ pub fn import_raw(drm: &DrmDevice, buf: &Nv12DmaBuf) -> Result( + device.create_texture_from_hal::( hal_tex, &wgpu::TextureDescriptor { label: Some("vaapi-plane"), diff --git a/lightningbeam-ui/gpu-video-encoder/src/encoder.rs b/lightningbeam-ui/gpu-video-encoder/src/encoder.rs index e334bac..c18d52a 100644 --- a/lightningbeam-ui/gpu-video-encoder/src/encoder.rs +++ b/lightningbeam-ui/gpu-video-encoder/src/encoder.rs @@ -215,7 +215,7 @@ impl ZeroCopyEncoder { uv_offset: uv.offset as u64, uv_pitch: uv.pitch as u64, }; - let imported = match dmabuf::import_raw(&self.drm, &buf) { + let imported = match dmabuf::import_raw(&self.drm.device, &self.drm.adapter, &buf) { Ok(i) => i, Err(e) => { ff::av_frame_free(&mut (drm_f as *mut _));