mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-04 20:38:06 +02:00
rusticl: implement cl_khr_priority_hints
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/35456>
This commit is contained in:
parent
1c3f238ce9
commit
79656dbcd3
7 changed files with 97 additions and 13 deletions
|
|
@ -835,7 +835,7 @@ Rusticl extensions that are not part of any OpenCL version:
|
|||
cl_khr_kernel_clock DONE (freedreno, iris, llvmpipe, nvc0, panfrost, radeonsi, zink, needs llvm-19)
|
||||
cl_khr_mipmap_image not started
|
||||
cl_khr_pci_bus_info DONE (iris, nvc0, radeonsi, zink)
|
||||
cl_khr_priority_hints not started
|
||||
cl_khr_priority_hints DONE (asahi, freedreno, iris, panfrost, radeonsi)
|
||||
cl_khr_spirv_extended_debug_info not started
|
||||
cl_khr_spirv_linkonce_odr DONE
|
||||
cl_khr_spirv_no_integer_wrap_decoration DONE
|
||||
|
|
|
|||
|
|
@ -49,3 +49,4 @@ VK_KHR_unified_image_layouts on RADV (RDNA3+)
|
|||
VK_KHR_vulkan_memory_model on panvk
|
||||
VK_KHR_present_wait2
|
||||
VK_EXT_descriptor_indexing on panvk/v10+
|
||||
cl_khr_priority_hints
|
||||
|
|
|
|||
|
|
@ -129,12 +129,23 @@ fn create_command_queue_with_properties(
|
|||
properties: *const cl_queue_properties,
|
||||
) -> CLResult<cl_command_queue> {
|
||||
let mut queue_properties = cl_command_queue_properties::default();
|
||||
let d = Device::ref_from_raw(device)?;
|
||||
|
||||
// SAFETY: properties is a 0 terminated array by spec.
|
||||
let properties = unsafe { Properties::new(properties) }.ok_or(CL_INVALID_PROPERTY)?;
|
||||
for (&key, &val) in properties.iter() {
|
||||
match u32::try_from(key).or(Err(CL_INVALID_PROPERTY))? {
|
||||
CL_QUEUE_PROPERTIES => queue_properties = val,
|
||||
CL_QUEUE_PRIORITY_KHR if d.context_priority_supported() != 0 => {
|
||||
let valid_props: cl_queue_properties = (CL_QUEUE_PRIORITY_LOW_KHR
|
||||
| CL_QUEUE_PRIORITY_MED_KHR
|
||||
| CL_QUEUE_PRIORITY_HIGH_KHR)
|
||||
.into();
|
||||
|
||||
if val & !valid_props != 0 {
|
||||
return Err(CL_INVALID_VALUE);
|
||||
}
|
||||
}
|
||||
// CL_INVALID_QUEUE_PROPERTIES if values specified in properties are valid but are not
|
||||
// supported by the device.
|
||||
CL_QUEUE_SIZE => return Err(CL_INVALID_QUEUE_PROPERTIES),
|
||||
|
|
|
|||
|
|
@ -707,6 +707,10 @@ impl DeviceBase {
|
|||
add_ext(1, 0, 0, "cl_khr_pci_bus_info");
|
||||
}
|
||||
|
||||
if self.context_priority_supported() != 0 {
|
||||
add_ext(1, 0, 0, "cl_khr_priority_hints");
|
||||
}
|
||||
|
||||
if self.screen().device_uuid().is_some() && self.screen().driver_uuid().is_some() {
|
||||
static_assert!(PIPE_UUID_SIZE == CL_UUID_SIZE_KHR);
|
||||
static_assert!(PIPE_LUID_SIZE == CL_LUID_SIZE_KHR);
|
||||
|
|
@ -912,6 +916,25 @@ impl DeviceBase {
|
|||
self.screen.caps().int64
|
||||
}
|
||||
|
||||
pub fn context_priority_supported(&self) -> cl_queue_priority_khr {
|
||||
let mut res = 0;
|
||||
let prio_mask = self.screen().caps().context_priority_mask;
|
||||
|
||||
if prio_mask & PIPE_CONTEXT_PRIORITY_LOW != 0 {
|
||||
res |= CL_QUEUE_PRIORITY_LOW_KHR;
|
||||
}
|
||||
if prio_mask & PIPE_CONTEXT_PRIORITY_MEDIUM != 0 {
|
||||
res |= CL_QUEUE_PRIORITY_MED_KHR;
|
||||
}
|
||||
if prio_mask & PIPE_CONTEXT_PRIORITY_HIGH != 0 {
|
||||
res |= CL_QUEUE_PRIORITY_HIGH_KHR;
|
||||
}
|
||||
|
||||
debug_assert!(prio_mask == 0 || prio_mask & CL_QUEUE_PRIORITY_MED_KHR != 0);
|
||||
|
||||
res
|
||||
}
|
||||
|
||||
pub fn global_mem_size(&self) -> cl_ulong {
|
||||
if let Some(memory_info) = self.screen.query_memory_info() {
|
||||
let memory: cl_ulong = if memory_info.total_device_memory != 0 {
|
||||
|
|
@ -1082,14 +1105,20 @@ impl DeviceBase {
|
|||
&self.screen
|
||||
}
|
||||
|
||||
pub fn create_context(&self) -> Option<PipeContext> {
|
||||
self.reusable_ctx()
|
||||
.pop()
|
||||
.or_else(|| self.screen.create_context())
|
||||
pub fn create_context(&self, prio: PipeContextPrio) -> Option<PipeContext> {
|
||||
// We only cache for Med prio contexts for now.
|
||||
let res = (prio == PipeContextPrio::Med)
|
||||
.then(|| self.reusable_ctx().pop())
|
||||
.flatten()
|
||||
.or_else(|| self.screen.create_context(prio))?;
|
||||
|
||||
debug_assert_eq!(res.prio, prio);
|
||||
|
||||
Some(res)
|
||||
}
|
||||
|
||||
pub fn recycle_context(&self, ctx: PipeContext) {
|
||||
if Platform::dbg().reuse_context {
|
||||
if Platform::dbg().reuse_context && ctx.prio == PipeContextPrio::Med {
|
||||
self.reusable_ctx().push(ctx);
|
||||
}
|
||||
}
|
||||
|
|
@ -1211,7 +1240,7 @@ impl Device {
|
|||
let screen = Arc::new(screen);
|
||||
// Create before loading libclc as llvmpipe only creates the shader cache with the first
|
||||
// context being created.
|
||||
let helper_ctx = screen.create_context()?;
|
||||
let helper_ctx = screen.create_context(PipeContextPrio::Med)?;
|
||||
let mut dev_base = DeviceBase {
|
||||
caps: DeviceCaps::new(&screen),
|
||||
helper_ctx: Mutex::new(helper_ctx),
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ use crate::impl_cl_type_trait;
|
|||
|
||||
use mesa_rust::compiler::nir::NirShader;
|
||||
use mesa_rust::pipe::context::PipeContext;
|
||||
use mesa_rust::pipe::context::PipeContextPrio;
|
||||
use mesa_rust_gen::*;
|
||||
use mesa_rust_util::properties::*;
|
||||
use rusticl_opencl_gen::*;
|
||||
|
|
@ -150,9 +151,17 @@ struct SendableQueueContext {
|
|||
}
|
||||
|
||||
impl SendableQueueContext {
|
||||
fn new(device: &'static Device) -> CLResult<Self> {
|
||||
fn new(device: &'static Device, prio: cl_queue_priority_khr) -> CLResult<Self> {
|
||||
let prio = if prio & CL_QUEUE_PRIORITY_HIGH_KHR != 0 {
|
||||
PipeContextPrio::High
|
||||
} else if prio & CL_QUEUE_PRIORITY_MED_KHR != 0 {
|
||||
PipeContextPrio::Med
|
||||
} else {
|
||||
PipeContextPrio::Low
|
||||
};
|
||||
|
||||
Ok(Self {
|
||||
ctx: ManuallyDrop::new(device.create_context().ok_or(CL_OUT_OF_HOST_MEMORY)?),
|
||||
ctx: ManuallyDrop::new(device.create_context(prio).ok_or(CL_OUT_OF_HOST_MEMORY)?),
|
||||
dev: device,
|
||||
})
|
||||
}
|
||||
|
|
@ -222,9 +231,21 @@ impl Queue {
|
|||
props: cl_command_queue_properties,
|
||||
props_v2: Properties<cl_queue_properties>,
|
||||
) -> CLResult<Arc<Queue>> {
|
||||
// If CL_QUEUE_PRIORITY_KHR is not specified, the default priority CL_QUEUE_PRIORITY_MED_KHR
|
||||
// is used.
|
||||
let mut prio = *props_v2
|
||||
.get(&CL_QUEUE_PRIORITY_KHR.into())
|
||||
.unwrap_or(&CL_QUEUE_PRIORITY_MED_KHR.into())
|
||||
as cl_queue_priority_khr;
|
||||
|
||||
// Fallback to the default priority if it's not supported by the device.
|
||||
if device.context_priority_supported() & prio == 0 {
|
||||
prio = CL_QUEUE_PRIORITY_MED_KHR;
|
||||
}
|
||||
|
||||
// we assume that memory allocation is the only possible failure. Any other failure reason
|
||||
// should be detected earlier (e.g.: checking for CAPs).
|
||||
let ctx = SendableQueueContext::new(device)?;
|
||||
let ctx = SendableQueueContext::new(device, prio)?;
|
||||
let (tx_q, rx_t) = mpsc::channel::<Vec<Arc<Event>>>();
|
||||
Ok(Arc::new(Self {
|
||||
base: CLObjectBase::new(RusticlTypes::Queue),
|
||||
|
|
|
|||
|
|
@ -14,9 +14,24 @@ use std::ptr;
|
|||
use std::ptr::*;
|
||||
use std::sync::Arc;
|
||||
|
||||
#[repr(u32)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
pub enum PipeContextPrio {
|
||||
Low = PIPE_CONTEXT_LOW_PRIORITY,
|
||||
Med = 0,
|
||||
High = PIPE_CONTEXT_HIGH_PRIORITY,
|
||||
}
|
||||
|
||||
impl From<PipeContextPrio> for u32 {
|
||||
fn from(value: PipeContextPrio) -> Self {
|
||||
value as _
|
||||
}
|
||||
}
|
||||
|
||||
pub struct PipeContext {
|
||||
pipe: NonNull<pipe_context>,
|
||||
screen: Arc<PipeScreen>,
|
||||
pub prio: PipeContextPrio,
|
||||
}
|
||||
|
||||
unsafe impl Send for PipeContext {}
|
||||
|
|
@ -36,10 +51,15 @@ impl From<RWFlags> for pipe_map_flags {
|
|||
}
|
||||
|
||||
impl PipeContext {
|
||||
pub(super) fn new(context: *mut pipe_context, screen: &Arc<PipeScreen>) -> Option<Self> {
|
||||
pub(super) fn new(
|
||||
context: *mut pipe_context,
|
||||
prio: PipeContextPrio,
|
||||
screen: &Arc<PipeScreen>,
|
||||
) -> Option<Self> {
|
||||
let s = Self {
|
||||
pipe: NonNull::new(context)?,
|
||||
screen: Arc::clone(screen),
|
||||
prio: prio,
|
||||
};
|
||||
|
||||
if !has_required_cbs(unsafe { s.pipe.as_ref() }) {
|
||||
|
|
|
|||
|
|
@ -83,15 +83,17 @@ impl PipeScreen {
|
|||
&self.screen().caps
|
||||
}
|
||||
|
||||
pub fn create_context(self: &Arc<Self>) -> Option<PipeContext> {
|
||||
pub fn create_context(self: &Arc<Self>, prio: PipeContextPrio) -> Option<PipeContext> {
|
||||
let flags: u32 = prio.into();
|
||||
PipeContext::new(
|
||||
unsafe {
|
||||
self.screen().context_create.unwrap()(
|
||||
self.screen.as_ptr(),
|
||||
ptr::null_mut(),
|
||||
PIPE_CONTEXT_COMPUTE_ONLY | PIPE_CONTEXT_NO_LOD_BIAS,
|
||||
flags | PIPE_CONTEXT_COMPUTE_ONLY | PIPE_CONTEXT_NO_LOD_BIAS,
|
||||
)
|
||||
},
|
||||
prio,
|
||||
self,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue