diff --git a/src/gallium/frontends/rusticl/mesa/pipe/context.rs b/src/gallium/frontends/rusticl/mesa/pipe/context.rs index 6c8a5cc63d6..369359c1745 100644 --- a/src/gallium/frontends/rusticl/mesa/pipe/context.rs +++ b/src/gallium/frontends/rusticl/mesa/pipe/context.rs @@ -1,7 +1,9 @@ extern crate mesa_rust_gen; use crate::compiler::nir::*; +use crate::pipe::fence::*; use crate::pipe::resource::*; +use crate::pipe::screen::*; use crate::pipe::transfer::*; use self::mesa_rust_gen::*; @@ -13,15 +15,17 @@ use std::sync::Arc; pub struct PipeContext { pipe: NonNull, + screen: Arc, } unsafe impl Send for PipeContext {} unsafe impl Sync for PipeContext {} impl PipeContext { - pub(super) fn new(context: *mut pipe_context) -> Option> { + pub(super) fn new(context: *mut pipe_context, screen: &Arc) -> Option> { let s = Self { pipe: NonNull::new(context)?, + screen: screen.clone(), }; if !has_required_cbs(unsafe { s.pipe.as_ref() }) { @@ -176,6 +180,14 @@ impl PipeContext { pub fn memory_barrier(&self, barriers: u32) { unsafe { self.pipe.as_ref().memory_barrier.unwrap()(self.pipe.as_ptr(), barriers) } } + + pub fn flush(&self) -> PipeFence { + unsafe { + let mut fence = ptr::null_mut(); + self.pipe.as_ref().flush.unwrap()(self.pipe.as_ptr(), &mut fence, 0); + PipeFence::new(fence, &self.screen) + } + } } impl Drop for PipeContext { @@ -195,6 +207,7 @@ fn has_required_cbs(c: &pipe_context) -> bool { && c.buffer_unmap.is_some() && c.create_compute_state.is_some() && c.delete_compute_state.is_some() + && c.flush.is_some() && c.launch_grid.is_some() && c.memory_barrier.is_some() && c.set_global_binding.is_some() diff --git a/src/gallium/frontends/rusticl/mesa/pipe/fence.rs b/src/gallium/frontends/rusticl/mesa/pipe/fence.rs new file mode 100644 index 00000000000..c47d6bb0333 --- /dev/null +++ b/src/gallium/frontends/rusticl/mesa/pipe/fence.rs @@ -0,0 +1,31 @@ +extern crate mesa_rust_gen; + +use crate::pipe::screen::*; + +use self::mesa_rust_gen::*; + +use std::sync::Arc; + +pub struct PipeFence { + fence: *mut pipe_fence_handle, + screen: Arc, +} + +impl PipeFence { + pub fn new(fence: *mut pipe_fence_handle, screen: &Arc) -> Self { + Self { + fence: fence, + screen: screen.clone(), + } + } + + pub fn wait(&self) { + self.screen.fence_finish(self.fence); + } +} + +impl Drop for PipeFence { + fn drop(&mut self) { + self.screen.unref_fence(self.fence); + } +} diff --git a/src/gallium/frontends/rusticl/mesa/pipe/mod.rs b/src/gallium/frontends/rusticl/mesa/pipe/mod.rs index e9b8d4840b5..38846ca8eac 100644 --- a/src/gallium/frontends/rusticl/mesa/pipe/mod.rs +++ b/src/gallium/frontends/rusticl/mesa/pipe/mod.rs @@ -1,5 +1,6 @@ pub mod context; pub mod device; +pub mod fence; pub mod resource; pub mod screen; pub mod transfer; diff --git a/src/gallium/frontends/rusticl/mesa/pipe/screen.rs b/src/gallium/frontends/rusticl/mesa/pipe/screen.rs index 3148a0e3fcc..60155e1f53c 100644 --- a/src/gallium/frontends/rusticl/mesa/pipe/screen.rs +++ b/src/gallium/frontends/rusticl/mesa/pipe/screen.rs @@ -71,13 +71,16 @@ impl PipeScreen { } pub fn create_context(self: &Arc) -> Option> { - PipeContext::new(unsafe { - (*self.screen).context_create.unwrap()( - self.screen, - ptr::null_mut(), - PIPE_CONTEXT_COMPUTE_ONLY, - ) - }) + PipeContext::new( + unsafe { + (*self.screen).context_create.unwrap()( + self.screen, + ptr::null_mut(), + PIPE_CONTEXT_COMPUTE_ONLY, + ) + }, + self, + ) } pub fn resource_create_buffer(&self, size: u32) -> Option { @@ -185,6 +188,20 @@ impl PipeScreen { } } } + + pub(super) fn unref_fence(&self, mut fence: *mut pipe_fence_handle) { + unsafe { + let s = &mut *self.screen; + s.fence_reference.unwrap()(s, &mut fence, ptr::null_mut()); + } + } + + pub(super) fn fence_finish(&self, fence: *mut pipe_fence_handle) { + unsafe { + let s = &mut *self.screen; + s.fence_finish.unwrap()(s, ptr::null_mut(), fence, PIPE_TIMEOUT_INFINITE as u64); + } + } } impl Drop for PipeScreen { @@ -199,6 +216,8 @@ fn has_required_cbs(screen: *mut pipe_screen) -> bool { let s = unsafe { *screen }; s.context_create.is_some() && s.destroy.is_some() + && s.fence_finish.is_some() + && s.fence_reference.is_some() && s.get_compiler_options.is_some() && s.get_compute_param.is_some() && s.get_name.is_some() diff --git a/src/gallium/frontends/rusticl/meson.build b/src/gallium/frontends/rusticl/meson.build index 80d8ebf8973..8e3b1e85b1d 100644 --- a/src/gallium/frontends/rusticl/meson.build +++ b/src/gallium/frontends/rusticl/meson.build @@ -36,6 +36,7 @@ libmesa_rust_files = files( 'mesa/compiler/clc/spirv.rs', 'mesa/pipe/context.rs', 'mesa/pipe/device.rs', + 'mesa/pipe/fence.rs', 'mesa/pipe/mod.rs', 'mesa/pipe/screen.rs', 'mesa/pipe/transfer.rs',