rusticl: implement clEnqueueReadBuffer

Signed-off-by: Karol Herbst <kherbst@redhat.com>
Acked-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15439>
This commit is contained in:
Karol Herbst 2022-03-12 20:02:04 +01:00 committed by Marge Bot
parent 4ec5f7b822
commit c430459310
3 changed files with 92 additions and 11 deletions

View file

@ -819,18 +819,27 @@ extern "C" fn cl_finish(command_queue: cl_command_queue) -> cl_int {
}
extern "C" fn cl_enqueue_read_buffer(
_command_queue: cl_command_queue,
_buffer: cl_mem,
_blocking_read: cl_bool,
_offset: usize,
_cb: usize,
_ptr: *mut ::std::os::raw::c_void,
_num_events_in_wait_list: cl_uint,
_event_wait_list: *const cl_event,
_event: *mut cl_event,
command_queue: cl_command_queue,
buffer: cl_mem,
blocking_read: cl_bool,
offset: usize,
cb: usize,
ptr: *mut ::std::os::raw::c_void,
num_events_in_wait_list: cl_uint,
event_wait_list: *const cl_event,
event: *mut cl_event,
) -> cl_int {
println!("cl_enqueue_read_buffer not implemented");
CL_OUT_OF_HOST_MEMORY
match_err!(enqueue_read_buffer(
command_queue,
buffer,
blocking_read,
offset,
cb,
ptr,
num_events_in_wait_list,
event_wait_list,
event
))
}
extern "C" fn cl_enqueue_write_buffer(

View file

@ -788,6 +788,58 @@ pub fn create_sampler(
Ok(cl_sampler::from_arc(sampler))
}
pub fn enqueue_read_buffer(
command_queue: cl_command_queue,
buffer: cl_mem,
blocking_read: cl_bool,
offset: usize,
cb: usize,
ptr: *mut ::std::os::raw::c_void,
num_events_in_wait_list: cl_uint,
event_wait_list: *const cl_event,
event: *mut cl_event,
) -> CLResult<()> {
let q = command_queue.get_arc()?;
let b = buffer.get_arc()?;
let block = check_cl_bool(blocking_read).ok_or(CL_INVALID_VALUE)?;
let evs = event_list_from_cl(&q, num_events_in_wait_list, event_wait_list)?;
// CL_INVALID_VALUE if the region being read or written specified by (offset, size) is out of
// bounds or if ptr is a NULL value.
if offset + cb > b.size || ptr.is_null() {
return Err(CL_INVALID_VALUE);
}
// CL_INVALID_CONTEXT if the context associated with command_queue and buffer are not the same
if b.context != q.context {
return Err(CL_INVALID_CONTEXT);
}
// CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST if the read and write operations are blocking
// and the execution status of any of the events in event_wait_list is a negative integer value.
if block && evs.iter().any(|e| e.is_error()) {
return Err(CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST);
}
// CL_INVALID_OPERATION if clEnqueueReadBuffer is called on buffer which has been created with
// CL_MEM_HOST_WRITE_ONLY or CL_MEM_HOST_NO_ACCESS.
if bit_check(b.flags, CL_MEM_HOST_WRITE_ONLY | CL_MEM_HOST_NO_ACCESS) {
return Err(CL_INVALID_OPERATION);
}
create_and_queue(
q,
CL_COMMAND_READ_BUFFER,
evs,
event,
block,
Box::new(move |q, ctx| b.read_to_user(q, ctx, offset, ptr, cb)),
)
// 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 device associated with queue.
}
pub fn enqueue_write_buffer(
command_queue: cl_command_queue,
buffer: cl_mem,

View file

@ -195,6 +195,26 @@ impl Mem {
.unwrap()
}
pub fn read_to_user(
&self,
q: &Arc<Queue>,
ctx: &Arc<PipeContext>,
offset: usize,
ptr: *mut c_void,
size: usize,
) -> CLResult<()> {
// TODO support sub buffers
let r = self.get_res().get(&q.device).unwrap();
let tx = ctx.buffer_map(r, 0, self.size.try_into().unwrap(), true);
unsafe {
ptr::copy_nonoverlapping(tx.ptr().add(offset), ptr, size);
}
drop(tx);
Ok(())
}
pub fn write_from_user(
&self,
q: &Arc<Queue>,