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>,

Reply via email to