mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 09:38:07 +02:00
rusticl/gl: flush and wait on gl objects inside clEnqueueAcquireGLObjects
This fixes flakes in the gl/gles OpenCL CTS tests on radeonsi and zink. Cc: mesa-stable Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/36249>
This commit is contained in:
parent
f6b844e239
commit
45c28a20a4
3 changed files with 93 additions and 70 deletions
|
|
@ -3184,13 +3184,27 @@ fn enqueue_acquire_gl_objects(
|
|||
return Err(CL_INVALID_GL_OBJECT);
|
||||
}
|
||||
|
||||
// We need to flush on the applications thread:
|
||||
//
|
||||
// If an OpenGL context is bound to the current thread, then any OpenGL commands which
|
||||
// 1. affect or access the contents of a memory object listed in the mem_objects list, and
|
||||
// 2. were issued on that OpenGL context prior to the call to clEnqueueAcquireGLObjects
|
||||
// will complete before execution of any OpenCL commands following the clEnqueueAcquireGLObjects
|
||||
// which affect or access any of those memory objects. If a non-NULL event object is returned,
|
||||
// it will report completion only after completion of such OpenGL commands.
|
||||
let fence_fd = q.context.flush_gl_mem_objects(&objs)?;
|
||||
create_and_queue(
|
||||
q,
|
||||
CL_COMMAND_ACQUIRE_GL_OBJECTS,
|
||||
evs,
|
||||
event,
|
||||
false,
|
||||
Box::new(move |_, ctx| copy_cube_to_slice(ctx, &objs)),
|
||||
Box::new(move |_, ctx| {
|
||||
if let Some(fence_fd) = fence_fd {
|
||||
ctx.import_fence(&fence_fd).gpu_wait(ctx);
|
||||
}
|
||||
copy_cube_to_slice(ctx, &objs)
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ use crate::core::util::*;
|
|||
use crate::impl_cl_type_trait;
|
||||
|
||||
use mesa_rust::pipe::context::RWFlags;
|
||||
use mesa_rust::pipe::fence::FenceFd;
|
||||
use mesa_rust::pipe::resource::*;
|
||||
use mesa_rust::pipe::screen::ResourceType;
|
||||
use mesa_rust_gen::*;
|
||||
|
|
@ -658,6 +659,11 @@ impl Context {
|
|||
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
pub fn flush_gl_mem_objects(&self, mem_objects: &[Mem]) -> CLResult<Option<FenceFd>> {
|
||||
let gl_ctx = self.gl_ctx_manager.as_ref().ok_or(CL_INVALID_CONTEXT)?;
|
||||
gl_ctx.flush(mem_objects)
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Context {
|
||||
|
|
|
|||
|
|
@ -206,6 +206,60 @@ impl GLCtxManager {
|
|||
}
|
||||
}
|
||||
|
||||
fn do_flush(&self, exports_in: &mut [mesa_glinterop_export_in]) -> CLResult<Option<FenceFd>> {
|
||||
let mut fd = -1;
|
||||
let mut flush_out = mesa_glinterop_flush_out {
|
||||
version: 1,
|
||||
fence_fd: &mut fd,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let err = match self.gl_ctx {
|
||||
GLCtx::EGL(disp, ctx) => {
|
||||
let egl_flush_objects_func = self
|
||||
.xplat_manager
|
||||
.MesaGLInteropEGLFlushObjects()?
|
||||
.ok_or(CL_INVALID_GL_SHAREGROUP_REFERENCE_KHR)?;
|
||||
|
||||
unsafe {
|
||||
egl_flush_objects_func(
|
||||
disp.cast(),
|
||||
ctx.cast(),
|
||||
exports_in.len() as u32,
|
||||
exports_in.as_mut_ptr(),
|
||||
&mut flush_out,
|
||||
)
|
||||
}
|
||||
}
|
||||
GLCtx::GLX(disp, ctx) => {
|
||||
let glx_flush_objects_func = self
|
||||
.xplat_manager
|
||||
.MesaGLInteropGLXFlushObjects()?
|
||||
.ok_or(CL_INVALID_GL_SHAREGROUP_REFERENCE_KHR)?;
|
||||
|
||||
unsafe {
|
||||
glx_flush_objects_func(
|
||||
disp.cast(),
|
||||
ctx.cast(),
|
||||
exports_in.len() as u32,
|
||||
exports_in.as_mut_ptr(),
|
||||
&mut flush_out,
|
||||
)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if err != 0 {
|
||||
return Err(interop_to_cl_error(err));
|
||||
}
|
||||
|
||||
if fd != -1 {
|
||||
Ok(Some(FenceFd { fd: fd }))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn export_object(
|
||||
&self,
|
||||
cl_ctx: &Arc<Context>,
|
||||
|
|
@ -229,13 +283,12 @@ impl GLCtxManager {
|
|||
..Default::default()
|
||||
};
|
||||
|
||||
let mut fd = -1;
|
||||
|
||||
let mut flush_out = mesa_glinterop_flush_out {
|
||||
version: 1,
|
||||
fence_fd: &mut fd,
|
||||
..Default::default()
|
||||
};
|
||||
if let Some(fence_fd) = self.do_flush(&mut [export_in])? {
|
||||
cl_ctx.devs.iter().for_each(|dev| {
|
||||
let fence = dev.helper_ctx().import_fence(&fence_fd);
|
||||
fence.wait();
|
||||
});
|
||||
}
|
||||
|
||||
let err = unsafe {
|
||||
match &self.gl_ctx {
|
||||
|
|
@ -244,74 +297,14 @@ impl GLCtxManager {
|
|||
.MesaGLInteropEGLExportObject()?
|
||||
.ok_or(CL_INVALID_GL_SHAREGROUP_REFERENCE_KHR)?;
|
||||
|
||||
let egl_flush_objects_func = xplat_manager
|
||||
.MesaGLInteropEGLFlushObjects()?
|
||||
.ok_or(CL_INVALID_GL_SHAREGROUP_REFERENCE_KHR)?;
|
||||
|
||||
let err_flush = egl_flush_objects_func(
|
||||
disp.cast(),
|
||||
ctx.cast(),
|
||||
1,
|
||||
&mut export_in,
|
||||
&mut flush_out,
|
||||
);
|
||||
|
||||
if err_flush != 0 {
|
||||
err_flush
|
||||
} else {
|
||||
if fd != -1 {
|
||||
// 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();
|
||||
});
|
||||
}
|
||||
|
||||
egl_export_object_func(
|
||||
disp.cast(),
|
||||
ctx.cast(),
|
||||
&mut export_in,
|
||||
&mut export_out,
|
||||
)
|
||||
}
|
||||
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)?;
|
||||
|
||||
let glx_flush_objects_func = xplat_manager
|
||||
.MesaGLInteropGLXFlushObjects()?
|
||||
.ok_or(CL_INVALID_GL_SHAREGROUP_REFERENCE_KHR)?;
|
||||
|
||||
let err_flush = glx_flush_objects_func(
|
||||
disp.cast(),
|
||||
ctx.cast(),
|
||||
1,
|
||||
&mut export_in,
|
||||
&mut flush_out,
|
||||
);
|
||||
|
||||
if err_flush != 0 {
|
||||
err_flush
|
||||
} else {
|
||||
if fd != -1 {
|
||||
// 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();
|
||||
});
|
||||
}
|
||||
|
||||
glx_export_object_func(
|
||||
disp.cast(),
|
||||
ctx.cast(),
|
||||
&mut export_in,
|
||||
&mut export_out,
|
||||
)
|
||||
}
|
||||
glx_export_object_func(disp.cast(), ctx.cast(), &mut export_in, &mut export_out)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -331,6 +324,16 @@ impl GLCtxManager {
|
|||
export_out: export_out,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn flush(&self, mem_objects: &[Mem]) -> CLResult<Option<FenceFd>> {
|
||||
let mut exports_in = mem_objects
|
||||
.iter()
|
||||
.filter_map(|m| m.gl_obj.as_ref())
|
||||
.map(|gl_obj| gl_obj.props)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
self.do_flush(&mut exports_in)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue