Module: Mesa Branch: main Commit: 59287a122381139c3deaa6ee85d9d044b0546840 URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=59287a122381139c3deaa6ee85d9d044b0546840
Author: Antonio Gomes <[email protected]> Date: Thu Oct 5 23:20:38 2023 -0300 rusticl: Flush objects just before importing them Reviewed-by: Karol Herbst <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21305> --- src/gallium/frontends/rusticl/api/memory.rs | 2 +- src/gallium/frontends/rusticl/core/device.rs | 5 ++ src/gallium/frontends/rusticl/core/gl.rs | 65 +++++++++++++++++++++- src/gallium/frontends/rusticl/mesa/pipe/context.rs | 14 +++++ src/gallium/frontends/rusticl/mesa/pipe/fence.rs | 13 +++++ 5 files changed, 96 insertions(+), 3 deletions(-) diff --git a/src/gallium/frontends/rusticl/api/memory.rs b/src/gallium/frontends/rusticl/api/memory.rs index c3216b28055..9fd77bfe806 100644 --- a/src/gallium/frontends/rusticl/api/memory.rs +++ b/src/gallium/frontends/rusticl/api/memory.rs @@ -2934,7 +2934,7 @@ fn create_from_gl( // CL_INVALID_CONTEXT if context [..] was not created from a GL context. if let Some(gl_ctx_manager) = gl_ctx_manager { let gl_export_manager = - gl_ctx_manager.export_object(target, flags as u32, miplevel, texture)?; + gl_ctx_manager.export_object(&c, target, flags as u32, miplevel, texture)?; Ok(cl_mem::from_arc(Mem::from_gl( c, diff --git a/src/gallium/frontends/rusticl/core/device.rs b/src/gallium/frontends/rusticl/core/device.rs index c1b003450b3..f66dc9ade2a 100644 --- a/src/gallium/frontends/rusticl/core/device.rs +++ b/src/gallium/frontends/rusticl/core/device.rs @@ -93,6 +93,7 @@ pub trait HelperContextWrapper { fn unmap(&self, tx: PipeTransfer); fn is_create_fence_fd_supported(&self) -> bool; + fn import_fence(&self, fence_fd: &FenceFd) -> PipeFence; } pub struct HelperContext<'a> { @@ -205,6 +206,10 @@ impl<'a> HelperContextWrapper for HelperContext<'a> { fn is_create_fence_fd_supported(&self) -> bool { self.lock.is_create_fence_fd_supported() } + + fn import_fence(&self, fd: &FenceFd) -> PipeFence { + self.lock.import_fence(fd) + } } impl_cl_type_trait!(cl_device_id, Device, CL_INVALID_DEVICE); diff --git a/src/gallium/frontends/rusticl/core/gl.rs b/src/gallium/frontends/rusticl/core/gl.rs index 2e5534822f2..f2a2d3cc631 100644 --- a/src/gallium/frontends/rusticl/core/gl.rs +++ b/src/gallium/frontends/rusticl/core/gl.rs @@ -1,5 +1,6 @@ use crate::api::icd::*; use crate::api::types::*; +use crate::core::context::*; use crate::core::device::*; use crate::core::format::*; use crate::core::memory::*; @@ -10,6 +11,7 @@ use libc_rust_gen::{close, dlsym}; use rusticl_opencl_gen::*; use mesa_rust::pipe::context::*; +use mesa_rust::pipe::fence::*; use mesa_rust::pipe::resource::*; use mesa_rust::pipe::screen::*; @@ -183,6 +185,7 @@ impl GLCtxManager { pub fn export_object( &self, + cl_ctx: &Arc<Context>, target: cl_GLenum, flags: u32, miplevel: cl_GLint, @@ -210,14 +213,72 @@ impl GLCtxManager { .MesaGLInteropEGLExportObject()? .ok_or(CL_INVALID_GL_SHAREGROUP_REFERENCE_KHR)?; - egl_export_object_func(disp.cast(), ctx.cast(), &mut export_in, &mut export_out) + let egl_flush_objects_func = xplat_manager + .MesaGLInteropEGLFlushObjects()? + .ok_or(CL_INVALID_GL_SHAREGROUP_REFERENCE_KHR)?; + + let mut fd = -1; + let err_flush = egl_flush_objects_func( + disp.cast(), + ctx.cast(), + 1, + &mut export_in, + ptr::null_mut(), + &mut fd, + ); + // TODO: use fence_server_sync in ctx inside the queue thread + let fence_fd = FenceFd { fd }; + cl_ctx.devs.iter().for_each(|dev| { + let fence = dev.helper_ctx().import_fence(&fence_fd); + fence.wait(); + }); + + if err_flush != 0 { + err_flush + } else { + egl_export_object_func( + disp.cast(), + ctx.cast(), + &mut export_in, + &mut export_out, + ) + } } GLCtx::GLX(disp, ctx) => { let glx_export_object_func = xplat_manager .MesaGLInteropGLXExportObject()? .ok_or(CL_INVALID_GL_SHAREGROUP_REFERENCE_KHR)?; - glx_export_object_func(disp.cast(), ctx.cast(), &mut export_in, &mut export_out) + let glx_flush_objects_func = xplat_manager + .MesaGLInteropGLXFlushObjects()? + .ok_or(CL_INVALID_GL_SHAREGROUP_REFERENCE_KHR)?; + + let mut fd = -1; + let err_flush = glx_flush_objects_func( + disp.cast(), + ctx.cast(), + 1, + &mut export_in, + ptr::null_mut(), + &mut fd, + ); + // TODO: use fence_server_sync in ctx inside the queue thread + let fence_fd = FenceFd { fd }; + cl_ctx.devs.iter().for_each(|dev| { + let fence = dev.helper_ctx().import_fence(&fence_fd); + fence.wait(); + }); + + if err_flush != 0 { + err_flush + } else { + glx_export_object_func( + disp.cast(), + ctx.cast(), + &mut export_in, + &mut export_out, + ) + } } } }; diff --git a/src/gallium/frontends/rusticl/mesa/pipe/context.rs b/src/gallium/frontends/rusticl/mesa/pipe/context.rs index 75dff224cb7..26512cbf8b4 100644 --- a/src/gallium/frontends/rusticl/mesa/pipe/context.rs +++ b/src/gallium/frontends/rusticl/mesa/pipe/context.rs @@ -4,6 +4,7 @@ use crate::pipe::resource::*; use crate::pipe::screen::*; use crate::pipe::transfer::*; +use mesa_rust_gen::pipe_fd_type::*; use mesa_rust_gen::*; use mesa_rust_util::has_required_feature; @@ -569,6 +570,19 @@ impl PipeContext { } } + pub fn import_fence(&self, fence_fd: &FenceFd) -> PipeFence { + unsafe { + let mut fence = ptr::null_mut(); + self.pipe.as_ref().create_fence_fd.unwrap()( + self.pipe.as_ptr(), + &mut fence, + fence_fd.fd, + PIPE_FD_TYPE_NATIVE_SYNC, + ); + PipeFence::new(fence, &self.screen) + } + } + pub fn svm_migrate( &self, ptrs: &[*const c_void], diff --git a/src/gallium/frontends/rusticl/mesa/pipe/fence.rs b/src/gallium/frontends/rusticl/mesa/pipe/fence.rs index d3e14eae934..c673dcce259 100644 --- a/src/gallium/frontends/rusticl/mesa/pipe/fence.rs +++ b/src/gallium/frontends/rusticl/mesa/pipe/fence.rs @@ -1,9 +1,22 @@ use crate::pipe::screen::*; +use libc_rust_gen::close; use mesa_rust_gen::*; use std::sync::Arc; +pub struct FenceFd { + pub fd: i32, +} + +impl Drop for FenceFd { + fn drop(&mut self) { + unsafe { + close(self.fd); + } + } +} + pub struct PipeFence { fence: *mut pipe_fence_handle, screen: Arc<PipeScreen>,
