mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-04 22:49:13 +02:00
rusticl/memory: make closures Send and Sync
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27747>
This commit is contained in:
parent
aa3b44c02b
commit
a97108d3c7
2 changed files with 107 additions and 20 deletions
|
|
@ -1060,6 +1060,8 @@ fn enqueue_read_buffer(
|
|||
return Err(CL_INVALID_OPERATION);
|
||||
}
|
||||
|
||||
// SAFETY: it's required that applications do not cause data races
|
||||
let ptr = unsafe { MutMemoryPtr::from_ptr(ptr) };
|
||||
create_and_queue(
|
||||
q,
|
||||
CL_COMMAND_READ_BUFFER,
|
||||
|
|
@ -1113,6 +1115,8 @@ fn enqueue_write_buffer(
|
|||
return Err(CL_INVALID_OPERATION);
|
||||
}
|
||||
|
||||
// SAFETY: it's required that applications do not cause data races
|
||||
let ptr = unsafe { ConstMemoryPtr::from_ptr(ptr) };
|
||||
create_and_queue(
|
||||
q,
|
||||
CL_COMMAND_WRITE_BUFFER,
|
||||
|
|
@ -1282,6 +1286,8 @@ fn enqueue_read_buffer_rect(
|
|||
return Err(CL_INVALID_CONTEXT);
|
||||
}
|
||||
|
||||
// SAFETY: it's required that applications do not cause data races
|
||||
let ptr = unsafe { MutMemoryPtr::from_ptr(ptr) };
|
||||
create_and_queue(
|
||||
q,
|
||||
CL_COMMAND_READ_BUFFER_RECT,
|
||||
|
|
@ -1405,6 +1411,8 @@ fn enqueue_write_buffer_rect(
|
|||
return Err(CL_INVALID_CONTEXT);
|
||||
}
|
||||
|
||||
// SAFETY: it's required that applications do not cause data races
|
||||
let ptr = unsafe { ConstMemoryPtr::from_ptr(ptr) };
|
||||
create_and_queue(
|
||||
q,
|
||||
CL_COMMAND_WRITE_BUFFER_RECT,
|
||||
|
|
@ -1670,7 +1678,7 @@ fn enqueue_map_buffer(
|
|||
Box::new(move |q, ctx| b.sync_shadow(q, ctx, ptr)),
|
||||
)?;
|
||||
|
||||
Ok(ptr)
|
||||
Ok(ptr.as_ptr())
|
||||
|
||||
// TODO
|
||||
// CL_MISALIGNED_SUB_BUFFER_OFFSET if buffer is a sub-buffer object and offset specified when the sub-buffer object is created is not aligned to CL_DEVICE_MEM_BASE_ADDR_ALIGN value for the device associated with queue. This error code is missing before version 1.1.
|
||||
|
|
@ -1741,6 +1749,8 @@ fn enqueue_read_image(
|
|||
slice_pitch = row_pitch * r[1];
|
||||
}
|
||||
|
||||
// SAFETY: it's required that applications do not cause data races
|
||||
let ptr = unsafe { MutMemoryPtr::from_ptr(ptr) };
|
||||
create_and_queue(
|
||||
q,
|
||||
CL_COMMAND_READ_IMAGE,
|
||||
|
|
@ -1819,6 +1829,8 @@ fn enqueue_write_image(
|
|||
slice_pitch = row_pitch * r[1];
|
||||
}
|
||||
|
||||
// SAFETY: it's required that applications do not cause data races
|
||||
let ptr = unsafe { ConstMemoryPtr::from_ptr(ptr) };
|
||||
create_and_queue(
|
||||
q,
|
||||
CL_COMMAND_WRITE_BUFFER_RECT,
|
||||
|
|
@ -2118,13 +2130,15 @@ fn enqueue_map_image(
|
|||
image_slice_pitch,
|
||||
)?;
|
||||
|
||||
// SAFETY: it's required that applications do not cause data races
|
||||
let sync_ptr = unsafe { MutMemoryPtr::from_ptr(ptr) };
|
||||
create_and_queue(
|
||||
q,
|
||||
CL_COMMAND_MAP_IMAGE,
|
||||
evs,
|
||||
event,
|
||||
block,
|
||||
Box::new(move |q, ctx| i.sync_shadow(q, ctx, ptr)),
|
||||
Box::new(move |q, ctx| i.sync_shadow(q, ctx, sync_ptr)),
|
||||
)?;
|
||||
|
||||
Ok(ptr)
|
||||
|
|
@ -2181,6 +2195,8 @@ fn enqueue_unmap_mem_object(
|
|||
return Err(CL_INVALID_VALUE);
|
||||
}
|
||||
|
||||
// SAFETY: it's required that applications do not cause data races
|
||||
let mapped_ptr = unsafe { MutMemoryPtr::from_ptr(mapped_ptr) };
|
||||
create_and_queue(
|
||||
q,
|
||||
CL_COMMAND_UNMAP_MEM_OBJECT,
|
||||
|
|
|
|||
|
|
@ -111,6 +111,50 @@ impl Mappings {
|
|||
}
|
||||
}
|
||||
|
||||
#[repr(transparent)]
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct ConstMemoryPtr {
|
||||
ptr: *const c_void,
|
||||
}
|
||||
unsafe impl Send for ConstMemoryPtr {}
|
||||
unsafe impl Sync for ConstMemoryPtr {}
|
||||
|
||||
impl ConstMemoryPtr {
|
||||
pub fn as_ptr(&self) -> *const c_void {
|
||||
self.ptr
|
||||
}
|
||||
|
||||
/// # Safety
|
||||
///
|
||||
/// Users need to ensure that `ptr` is only accessed in a thread-safe manner sufficient for
|
||||
/// [Send] and [Sync]
|
||||
pub unsafe fn from_ptr(ptr: *const c_void) -> Self {
|
||||
Self { ptr: ptr }
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(transparent)]
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct MutMemoryPtr {
|
||||
ptr: *mut c_void,
|
||||
}
|
||||
unsafe impl Send for MutMemoryPtr {}
|
||||
unsafe impl Sync for MutMemoryPtr {}
|
||||
|
||||
impl MutMemoryPtr {
|
||||
pub fn as_ptr(&self) -> *mut c_void {
|
||||
self.ptr
|
||||
}
|
||||
|
||||
/// # Safety
|
||||
///
|
||||
/// Users need to ensure that `ptr` is only accessed in a thread-safe manner sufficient for
|
||||
/// [Send] and [Sync]
|
||||
pub unsafe fn from_ptr(ptr: *mut c_void) -> Self {
|
||||
Self { ptr: ptr }
|
||||
}
|
||||
}
|
||||
|
||||
pub enum Mem {
|
||||
Buffer(Arc<Buffer>),
|
||||
Image(Arc<Image>),
|
||||
|
|
@ -128,7 +172,7 @@ impl Deref for Mem {
|
|||
}
|
||||
|
||||
impl Mem {
|
||||
pub fn unmap(&self, q: &Queue, ctx: &PipeContext, ptr: *mut c_void) -> CLResult<()> {
|
||||
pub fn unmap(&self, q: &Queue, ctx: &PipeContext, ptr: MutMemoryPtr) -> CLResult<()> {
|
||||
match self {
|
||||
Self::Buffer(b) => b.unmap(q, ctx, ptr),
|
||||
Self::Image(i) => i.unmap(q, ctx, ptr),
|
||||
|
|
@ -851,7 +895,7 @@ impl Buffer {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn map(&self, dev: &'static Device, offset: usize) -> CLResult<*mut c_void> {
|
||||
pub fn map(&self, dev: &'static Device, offset: usize) -> CLResult<MutMemoryPtr> {
|
||||
let ptr = if self.has_user_shadow_buffer(dev)? {
|
||||
self.host_ptr()
|
||||
} else {
|
||||
|
|
@ -868,7 +912,8 @@ impl Buffer {
|
|||
};
|
||||
|
||||
let ptr = unsafe { ptr.add(offset) };
|
||||
Ok(ptr)
|
||||
// SAFETY: it's required that applications do not cause data races
|
||||
Ok(unsafe { MutMemoryPtr::from_ptr(ptr) })
|
||||
}
|
||||
|
||||
pub fn read(
|
||||
|
|
@ -876,9 +921,10 @@ impl Buffer {
|
|||
q: &Queue,
|
||||
ctx: &PipeContext,
|
||||
offset: usize,
|
||||
ptr: *mut c_void,
|
||||
ptr: MutMemoryPtr,
|
||||
size: usize,
|
||||
) -> CLResult<()> {
|
||||
let ptr = ptr.as_ptr();
|
||||
let tx = self.tx(q, ctx, offset, size, RWFlags::RD)?;
|
||||
|
||||
unsafe {
|
||||
|
|
@ -890,7 +936,7 @@ impl Buffer {
|
|||
|
||||
pub fn read_rect(
|
||||
&self,
|
||||
dst: *mut c_void,
|
||||
dst: MutMemoryPtr,
|
||||
q: &Queue,
|
||||
ctx: &PipeContext,
|
||||
region: &CLVec<usize>,
|
||||
|
|
@ -901,6 +947,7 @@ impl Buffer {
|
|||
dst_row_pitch: usize,
|
||||
dst_slice_pitch: usize,
|
||||
) -> CLResult<()> {
|
||||
let dst = dst.as_ptr();
|
||||
let (offset, size) =
|
||||
CLVec::calc_offset_size(src_origin, region, [1, src_row_pitch, src_slice_pitch]);
|
||||
let tx = self.tx(q, ctx, offset, size, RWFlags::RD)?;
|
||||
|
|
@ -922,14 +969,22 @@ impl Buffer {
|
|||
}
|
||||
|
||||
// TODO: only sync on map when the memory is not mapped with discard
|
||||
pub fn sync_shadow(&self, q: &Queue, ctx: &PipeContext, ptr: *mut c_void) -> CLResult<()> {
|
||||
pub fn sync_shadow(&self, q: &Queue, ctx: &PipeContext, ptr: MutMemoryPtr) -> CLResult<()> {
|
||||
let ptr = ptr.as_ptr();
|
||||
let mut lock = self.maps.lock().unwrap();
|
||||
if !lock.increase_ref(q.device, ptr) {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
if self.has_user_shadow_buffer(q.device)? {
|
||||
self.read(q, ctx, 0, self.host_ptr(), self.size)
|
||||
self.read(
|
||||
q,
|
||||
ctx,
|
||||
0,
|
||||
// SAFETY: it's required that applications do not cause data races
|
||||
unsafe { MutMemoryPtr::from_ptr(self.host_ptr()) },
|
||||
self.size,
|
||||
)
|
||||
} else {
|
||||
if let Some(shadow) = lock.tx.get(&q.device).and_then(|tx| tx.shadow.as_ref()) {
|
||||
let res = self.get_res_of_dev(q.device)?;
|
||||
|
|
@ -998,7 +1053,8 @@ impl Buffer {
|
|||
}
|
||||
|
||||
// TODO: only sync on unmap when the memory is not mapped for writing
|
||||
pub fn unmap(&self, q: &Queue, ctx: &PipeContext, ptr: *mut c_void) -> CLResult<()> {
|
||||
pub fn unmap(&self, q: &Queue, ctx: &PipeContext, ptr: MutMemoryPtr) -> CLResult<()> {
|
||||
let ptr = ptr.as_ptr();
|
||||
let mut lock = self.maps.lock().unwrap();
|
||||
if !lock.contains_ptr(ptr) {
|
||||
return Ok(());
|
||||
|
|
@ -1017,7 +1073,14 @@ impl Buffer {
|
|||
|
||||
ctx.resource_copy_region(shadow, res, &[offset, 0, 0], &bx);
|
||||
} else if self.has_user_shadow_buffer(q.device)? {
|
||||
self.write(q, ctx, 0, self.host_ptr(), self.size)?;
|
||||
self.write(
|
||||
q,
|
||||
ctx,
|
||||
0,
|
||||
// SAFETY: it's required that applications do not cause data races
|
||||
unsafe { ConstMemoryPtr::from_ptr(self.host_ptr()) },
|
||||
self.size,
|
||||
)?;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1031,9 +1094,10 @@ impl Buffer {
|
|||
q: &Queue,
|
||||
ctx: &PipeContext,
|
||||
offset: usize,
|
||||
ptr: *const c_void,
|
||||
ptr: ConstMemoryPtr,
|
||||
size: usize,
|
||||
) -> CLResult<()> {
|
||||
let ptr = ptr.as_ptr();
|
||||
let offset = self.apply_offset(offset)?;
|
||||
let r = self.get_res_of_dev(q.device)?;
|
||||
ctx.buffer_subdata(
|
||||
|
|
@ -1047,7 +1111,7 @@ impl Buffer {
|
|||
|
||||
pub fn write_rect(
|
||||
&self,
|
||||
src: *const c_void,
|
||||
src: ConstMemoryPtr,
|
||||
q: &Queue,
|
||||
ctx: &PipeContext,
|
||||
region: &CLVec<usize>,
|
||||
|
|
@ -1058,6 +1122,7 @@ impl Buffer {
|
|||
dst_row_pitch: usize,
|
||||
dst_slice_pitch: usize,
|
||||
) -> CLResult<()> {
|
||||
let src = src.as_ptr();
|
||||
let (offset, size) =
|
||||
CLVec::calc_offset_size(dst_origin, region, [1, dst_row_pitch, dst_slice_pitch]);
|
||||
let tx = self.tx(q, ctx, offset, size, RWFlags::WR)?;
|
||||
|
|
@ -1302,7 +1367,7 @@ impl Image {
|
|||
} else if let Some(Mem::Buffer(buffer)) = &self.parent {
|
||||
*row_pitch = self.image_desc.image_row_pitch;
|
||||
*slice_pitch = self.image_desc.image_slice_pitch;
|
||||
buffer.map(dev, 0)?
|
||||
buffer.map(dev, 0)?.as_ptr()
|
||||
} else {
|
||||
let mut lock = self.maps.lock().unwrap();
|
||||
|
||||
|
|
@ -1355,7 +1420,7 @@ impl Image {
|
|||
|
||||
pub fn read(
|
||||
&self,
|
||||
dst: *mut c_void,
|
||||
dst: MutMemoryPtr,
|
||||
q: &Queue,
|
||||
ctx: &PipeContext,
|
||||
region: &CLVec<usize>,
|
||||
|
|
@ -1363,6 +1428,7 @@ impl Image {
|
|||
dst_row_pitch: usize,
|
||||
dst_slice_pitch: usize,
|
||||
) -> CLResult<()> {
|
||||
let dst = dst.as_ptr();
|
||||
let pixel_size = self.image_format.pixel_size().unwrap();
|
||||
|
||||
let tx;
|
||||
|
|
@ -1403,7 +1469,8 @@ impl Image {
|
|||
}
|
||||
|
||||
// TODO: only sync on map when the memory is not mapped with discard
|
||||
pub fn sync_shadow(&self, q: &Queue, ctx: &PipeContext, ptr: *mut c_void) -> CLResult<()> {
|
||||
pub fn sync_shadow(&self, q: &Queue, ctx: &PipeContext, ptr: MutMemoryPtr) -> CLResult<()> {
|
||||
let ptr = ptr.as_ptr();
|
||||
let mut lock = self.maps.lock().unwrap();
|
||||
if !lock.increase_ref(q.device, ptr) {
|
||||
return Ok(());
|
||||
|
|
@ -1411,7 +1478,8 @@ impl Image {
|
|||
|
||||
if self.has_user_shadow_buffer(q.device)? {
|
||||
self.read(
|
||||
self.host_ptr(),
|
||||
// SAFETY: it's required that applications do not cause data races
|
||||
unsafe { MutMemoryPtr::from_ptr(self.host_ptr()) },
|
||||
q,
|
||||
ctx,
|
||||
&self.image_desc.size(),
|
||||
|
|
@ -1482,7 +1550,8 @@ impl Image {
|
|||
}
|
||||
|
||||
// TODO: only sync on unmap when the memory is not mapped for writing
|
||||
pub fn unmap(&self, q: &Queue, ctx: &PipeContext, ptr: *mut c_void) -> CLResult<()> {
|
||||
pub fn unmap(&self, q: &Queue, ctx: &PipeContext, ptr: MutMemoryPtr) -> CLResult<()> {
|
||||
let ptr = ptr.as_ptr();
|
||||
let mut lock = self.maps.lock().unwrap();
|
||||
if !lock.contains_ptr(ptr) {
|
||||
return Ok(());
|
||||
|
|
@ -1496,7 +1565,8 @@ impl Image {
|
|||
ctx.resource_copy_region(shadow, res, &[0, 0, 0], &bx);
|
||||
} else if self.has_user_shadow_buffer(q.device)? {
|
||||
self.write(
|
||||
self.host_ptr(),
|
||||
// SAFETY: it's required that applications do not cause data races
|
||||
unsafe { ConstMemoryPtr::from_ptr(self.host_ptr()) },
|
||||
q,
|
||||
ctx,
|
||||
&self.image_desc.size(),
|
||||
|
|
@ -1514,7 +1584,7 @@ impl Image {
|
|||
|
||||
pub fn write(
|
||||
&self,
|
||||
src: *const c_void,
|
||||
src: ConstMemoryPtr,
|
||||
q: &Queue,
|
||||
ctx: &PipeContext,
|
||||
region: &CLVec<usize>,
|
||||
|
|
@ -1522,6 +1592,7 @@ impl Image {
|
|||
mut src_slice_pitch: usize,
|
||||
dst_origin: &CLVec<usize>,
|
||||
) -> CLResult<()> {
|
||||
let src = src.as_ptr();
|
||||
let dst_row_pitch = self.image_desc.image_row_pitch;
|
||||
let dst_slice_pitch = self.image_desc.image_slice_pitch;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue