diff --git a/rutabaga_gfx/src/cross_domain/cross_domain.rs b/rutabaga_gfx/src/cross_domain/cross_domain.rs index 71ecf6eb75..de6a283252 100644 --- a/rutabaga_gfx/src/cross_domain/cross_domain.rs +++ b/rutabaga_gfx/src/cross_domain/cross_domain.rs @@ -791,6 +791,7 @@ impl RutabagaContext for CrossDomainContext { info_3d: Some(info_3d), vulkan_info: reqs.vulkan_info, backing_iovecs: None, + import_mask: 0, }) } _ => Err(RutabagaError::InvalidCrossDomainItemType), @@ -821,6 +822,7 @@ impl RutabagaContext for CrossDomainContext { info_3d: None, vulkan_info: None, backing_iovecs: None, + import_mask: 0, }) } _ => Err(RutabagaError::InvalidCrossDomainItemType), @@ -974,6 +976,7 @@ impl RutabagaComponent for CrossDomain { info_3d: None, vulkan_info: None, backing_iovecs: iovec_opt, + import_mask: 0, }) } diff --git a/rutabaga_gfx/src/gfxstream.rs b/rutabaga_gfx/src/gfxstream.rs index af06e8a51d..e8bc8de4d4 100644 --- a/rutabaga_gfx/src/gfxstream.rs +++ b/rutabaga_gfx/src/gfxstream.rs @@ -390,6 +390,7 @@ impl RutabagaComponent for Gfxstream { info_3d: None, vulkan_info: None, backing_iovecs: None, + import_mask: 0, }) } @@ -560,6 +561,7 @@ impl RutabagaComponent for Gfxstream { info_3d: None, vulkan_info: None, backing_iovecs: iovec_opt, + import_mask: 0, }) } diff --git a/rutabaga_gfx/src/rutabaga_2d.rs b/rutabaga_gfx/src/rutabaga_2d.rs index 579b3393ae..cf9a8bacd2 100644 --- a/rutabaga_gfx/src/rutabaga_2d.rs +++ b/rutabaga_gfx/src/rutabaga_2d.rs @@ -183,6 +183,7 @@ impl RutabagaComponent for Rutabaga2D { info_3d: None, vulkan_info: None, backing_iovecs: None, + import_mask: 0, }) } diff --git a/rutabaga_gfx/src/rutabaga_core.rs b/rutabaga_gfx/src/rutabaga_core.rs index 80bc702fa5..563b5c8b53 100644 --- a/rutabaga_gfx/src/rutabaga_core.rs +++ b/rutabaga_gfx/src/rutabaga_core.rs @@ -40,6 +40,9 @@ pub struct RutabagaResource { pub info_3d: Option, pub vulkan_info: Option, pub backing_iovecs: Option>, + + /// Bitmask of components that have already imported this resource + pub import_mask: u32, } /// A RutabagaComponent is a building block of the Virtual Graphics Interface (VGI). Each component diff --git a/rutabaga_gfx/src/virgl_renderer.rs b/rutabaga_gfx/src/virgl_renderer.rs index 7caecda1a9..c07ac0a6e5 100644 --- a/rutabaga_gfx/src/virgl_renderer.rs +++ b/rutabaga_gfx/src/virgl_renderer.rs @@ -45,6 +45,43 @@ struct VirglRendererContext { ctx_id: u32, } +fn import_resource(resource: &mut RutabagaResource) { + if (resource.import_mask & (1 << (RutabagaComponentType::VirglRenderer as u32))) != 0 { + return; + } + + if let Some(handle) = &resource.handle { + if handle.handle_type == RUTABAGA_MEM_HANDLE_TYPE_DMABUF { + if let Ok(dmabuf_fd) = base::clone_descriptor(&handle.os_handle) { + // Safe because we are being passed a valid fd + unsafe { + let dmabuf_size = libc::lseek64(dmabuf_fd, 0, libc::SEEK_END); + libc::lseek64(dmabuf_fd, 0, libc::SEEK_SET); + let args = virgl_renderer_resource_import_blob_args { + res_handle: resource.resource_id, + blob_mem: resource.blob_mem, + fd_type: VIRGL_RENDERER_BLOB_FD_TYPE_DMABUF, + fd: dmabuf_fd, + size: dmabuf_size as u64, + }; + let ret = virgl_renderer_resource_import_blob(&args); + if ret != 0 { + // import_blob can fail if we've previously imported this resource, + // but in any case virglrenderer does not take ownership of the fd + // in error paths + // + // Because of the re-import case we must still fall through to the + // virgl_renderer_ctx_attach_resource() call. + libc::close(dmabuf_fd); + return; + } + resource.import_mask |= 1 << (RutabagaComponentType::VirglRenderer as u32); + } + } + } + } +} + impl RutabagaContext for VirglRendererContext { fn submit_cmd(&mut self, commands: &mut [u8]) -> RutabagaResult<()> { if commands.len() % size_of::() != 0 { @@ -64,6 +101,8 @@ impl RutabagaContext for VirglRendererContext { } fn attach(&mut self, resource: &mut RutabagaResource) { + import_resource(resource); + // The context id and resource id must be valid because the respective instances ensure // their lifetime. unsafe { @@ -444,6 +483,7 @@ impl RutabagaComponent for VirglRenderer { info_3d: self.query(resource_id).ok(), vulkan_info: None, backing_iovecs: None, + import_mask: 1 << (RutabagaComponentType::VirglRenderer as u32), }) } @@ -609,6 +649,7 @@ impl RutabagaComponent for VirglRenderer { info_3d: self.query(resource_id).ok(), vulkan_info: None, backing_iovecs: iovec_opt, + import_mask: 1 << (RutabagaComponentType::VirglRenderer as u32), }) } #[cfg(not(feature = "virgl_renderer_next"))] diff --git a/third_party/virglrenderer b/third_party/virglrenderer index 2a5fb800c6..4770f706db 160000 --- a/third_party/virglrenderer +++ b/third_party/virglrenderer @@ -1 +1 @@ -Subproject commit 2a5fb800c6b0ce15ad37c2c698635e3e2d27b37c +Subproject commit 4770f706db2d0e7731264cb36a659c764c7787f1