rusticl: add QueueContext to track GPU state
Signed-off-by: Karol Herbst <kherbst@redhat.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25946>
This commit is contained in:
@@ -4,7 +4,6 @@ use crate::core::context::*;
|
||||
use crate::core::queue::*;
|
||||
use crate::impl_cl_type_trait;
|
||||
|
||||
use mesa_rust::pipe::context::*;
|
||||
use mesa_rust::pipe::query::*;
|
||||
use mesa_rust_gen::*;
|
||||
use mesa_rust_util::static_assert;
|
||||
@@ -24,7 +23,7 @@ static_assert!(CL_RUNNING == 1);
|
||||
static_assert!(CL_SUBMITTED == 2);
|
||||
static_assert!(CL_QUEUED == 3);
|
||||
|
||||
pub type EventSig = Box<dyn FnOnce(&Arc<Queue>, &PipeContext) -> CLResult<()>>;
|
||||
pub type EventSig = Box<dyn FnOnce(&Arc<Queue>, &QueueContext) -> CLResult<()>>;
|
||||
|
||||
pub enum EventTimes {
|
||||
Queued = CL_PROFILING_COMMAND_QUEUED as isize,
|
||||
@@ -194,7 +193,7 @@ impl Event {
|
||||
// We always assume that work here simply submits stuff to the hardware even if it's just doing
|
||||
// sw emulation or nothing at all.
|
||||
// If anything requets waiting, we will update the status through fencing later.
|
||||
pub fn call(&self, ctx: &PipeContext) {
|
||||
pub fn call(&self, ctx: &QueueContext) {
|
||||
let mut lock = self.state();
|
||||
let status = lock.status;
|
||||
let queue = self.queue.as_ref().unwrap();
|
||||
|
||||
@@ -10,6 +10,7 @@ use mesa_rust_util::properties::*;
|
||||
use rusticl_opencl_gen::*;
|
||||
|
||||
use std::mem;
|
||||
use std::ops::Deref;
|
||||
use std::sync::mpsc;
|
||||
use std::sync::Arc;
|
||||
use std::sync::Mutex;
|
||||
@@ -17,6 +18,33 @@ use std::sync::Weak;
|
||||
use std::thread;
|
||||
use std::thread::JoinHandle;
|
||||
|
||||
/// State tracking wrapper for [PipeContext]
|
||||
///
|
||||
/// Used for tracking bound GPU state to lower CPU overhead and centralize state tracking
|
||||
pub struct QueueContext {
|
||||
ctx: PipeContext,
|
||||
}
|
||||
|
||||
impl QueueContext {
|
||||
fn new_for(device: &Device) -> CLResult<Self> {
|
||||
Ok(Self {
|
||||
ctx: device
|
||||
.screen()
|
||||
.create_context()
|
||||
.ok_or(CL_OUT_OF_HOST_MEMORY)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// This should go once we moved all state tracking into QueueContext
|
||||
impl Deref for QueueContext {
|
||||
type Target = PipeContext;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.ctx
|
||||
}
|
||||
}
|
||||
|
||||
struct QueueState {
|
||||
pending: Vec<Arc<Event>>,
|
||||
last: Weak<Event>,
|
||||
@@ -53,7 +81,7 @@ impl Queue {
|
||||
) -> CLResult<Arc<Queue>> {
|
||||
// we assume that memory allocation is the only possible failure. Any other failure reason
|
||||
// should be detected earlier (e.g.: checking for CAPs).
|
||||
let pipe = device.screen().create_context().unwrap();
|
||||
let ctx = QueueContext::new_for(device)?;
|
||||
let (tx_q, rx_t) = mpsc::channel::<Vec<Arc<Event>>>();
|
||||
Ok(Arc::new(Self {
|
||||
base: CLObjectBase::new(),
|
||||
@@ -81,7 +109,7 @@ impl Queue {
|
||||
// If we hit any deps from another queue, flush so we don't risk a dead
|
||||
// lock.
|
||||
if e.deps.iter().any(|ev| ev.queue != e.queue) {
|
||||
flush_events(&mut flushed, &pipe);
|
||||
flush_events(&mut flushed, &ctx);
|
||||
}
|
||||
|
||||
// We have to wait on user events or events from other queues.
|
||||
@@ -98,25 +126,25 @@ impl Queue {
|
||||
continue;
|
||||
}
|
||||
|
||||
e.call(&pipe);
|
||||
e.call(&ctx);
|
||||
|
||||
if e.is_user() {
|
||||
// On each user event we flush our events as application might
|
||||
// wait on them before signaling user events.
|
||||
flush_events(&mut flushed, &pipe);
|
||||
flush_events(&mut flushed, &ctx);
|
||||
|
||||
// Wait on user events as they are synchronization points in the
|
||||
// application's control.
|
||||
e.wait();
|
||||
} else if Platform::dbg().sync_every_event {
|
||||
flushed.push(e);
|
||||
flush_events(&mut flushed, &pipe);
|
||||
flush_events(&mut flushed, &ctx);
|
||||
} else {
|
||||
flushed.push(e);
|
||||
}
|
||||
}
|
||||
|
||||
flush_events(&mut flushed, &pipe);
|
||||
flush_events(&mut flushed, &ctx);
|
||||
})
|
||||
.unwrap(),
|
||||
}))
|
||||
|
||||
Reference in New Issue
Block a user