[Beignet] [PATCH] Correct clEnqueueReadBuffer, clEnqueueWriteBuffer and clEnqueueMapBuffer
Dag Lem
dag at nimrod.no
Sat May 25 02:34:26 PDT 2013
This implements handling of the offset parameter, and adds sanity
checks according to spec.
A bug is fixed in clEnqueueReadBuffer, where the buffer was not
unmapped after copying.
Signed-off-by: Dag Lem <dag at nimrod.no>
---
src/cl_api.c | 104 ++++++++++++++++++++++++++++++++++++++++++++++++-----------
1 file changed, 85 insertions(+), 19 deletions(-)
diff --git a/src/cl_api.c b/src/cl_api.c
index f378296..9c5943b 100644
--- a/src/cl_api.c
+++ b/src/cl_api.c
@@ -848,19 +848,46 @@ clEnqueueReadBuffer(cl_command_queue command_queue,
cl_mem buffer,
cl_bool blocking_read,
size_t offset,
- size_t cb,
+ size_t size,
void * ptr,
cl_uint num_events_in_wait_list,
const cl_event * event_wait_list,
cl_event * event)
{
- cl_int err = CL_SUCCESS;
- assert(ptr != NULL);
- void* temp_ptr = NULL;
- temp_ptr = clMapBufferIntel(buffer, &err);
- assert(err == CL_SUCCESS);
- memcpy(ptr, temp_ptr, cb);
- return err;
+ cl_int err = CL_SUCCESS;
+ void* src_ptr;
+
+ CHECK_QUEUE(command_queue);
+ CHECK_MEM(buffer);
+ if (command_queue->ctx != buffer->ctx) {
+ err = CL_INVALID_CONTEXT;
+ goto error;
+ }
+
+ if (blocking_read != CL_TRUE)
+ NOT_IMPLEMENTED;
+
+ if (!ptr || !size || offset + size > buffer->size) {
+ err = CL_INVALID_VALUE;
+ goto error;
+ }
+
+ if (buffer->flags & (CL_MEM_HOST_WRITE_ONLY | CL_MEM_HOST_NO_ACCESS)) {
+ err = CL_INVALID_OPERATION;
+ goto error;
+ }
+
+ if (!(src_ptr = cl_mem_map_auto(buffer))) {
+ err = CL_MAP_FAILURE;
+ goto error;
+ }
+
+ memcpy(ptr, (char*)src_ptr + offset, size);
+
+ err = cl_mem_unmap_auto(buffer);
+
+error:
+ return err;
}
cl_int
@@ -888,20 +915,45 @@ clEnqueueWriteBuffer(cl_command_queue command_queue,
cl_mem buffer,
cl_bool blocking_write,
size_t offset,
- size_t cb,
+ size_t size,
const void * ptr,
cl_uint num_events_in_wait_list,
const cl_event * event_wait_list,
cl_event * event)
{
+ cl_int err = CL_SUCCESS;
+ void* dst_ptr;
+
+ CHECK_QUEUE(command_queue);
+ CHECK_MEM(buffer);
+ if (command_queue->ctx != buffer->ctx) {
+ err = CL_INVALID_CONTEXT;
+ goto error;
+ }
+
if (blocking_write != CL_TRUE)
NOT_IMPLEMENTED;
- cl_int err;
- void *p = clMapBufferIntel(buffer, &err);
- if (err != CL_SUCCESS)
- return err;
- memcpy(p + offset, ptr, cb);
- err = clUnmapBufferIntel(buffer);
+
+ if (!ptr || !size || offset + size > buffer->size) {
+ err = CL_INVALID_VALUE;
+ goto error;
+ }
+
+ if (buffer->flags & (CL_MEM_HOST_READ_ONLY | CL_MEM_HOST_NO_ACCESS)) {
+ err = CL_INVALID_OPERATION;
+ goto error;
+ }
+
+ if (!(dst_ptr = cl_mem_map_auto(buffer))) {
+ err = CL_MAP_FAILURE;
+ goto error;
+ }
+
+ memcpy((char*)dst_ptr + offset, ptr, size);
+
+ err = cl_mem_unmap_auto(buffer);
+
+error:
return err;
}
@@ -1200,7 +1252,7 @@ clEnqueueMapBuffer(cl_command_queue command_queue,
cl_bool blocking_map,
cl_map_flags map_flags,
size_t offset,
- size_t cb,
+ size_t size,
cl_uint num_events_in_wait_list,
const cl_event * event_wait_list,
cl_event * event,
@@ -1217,15 +1269,29 @@ clEnqueueMapBuffer(cl_command_queue command_queue,
}
if (blocking_map != CL_TRUE)
- NOT_IMPLEMENTED;
- if (offset != 0)
- NOT_IMPLEMENTED;
+ NOT_IMPLEMENTED;
+
+ if (!size || offset + size > buffer->size) {
+ err = CL_INVALID_VALUE;
+ goto error;
+ }
+
+ if ((map_flags & CL_MAP_READ &&
+ buffer->flags & (CL_MEM_HOST_WRITE_ONLY | CL_MEM_HOST_NO_ACCESS)) ||
+ (map_flags & (CL_MAP_WRITE | CL_MAP_WRITE_INVALIDATE_REGION) &&
+ buffer->flags & (CL_MEM_HOST_READ_ONLY | CL_MEM_HOST_NO_ACCESS)))
+ {
+ err = CL_INVALID_OPERATION;
+ goto error;
+ }
if (!(ptr = cl_mem_map_auto(buffer))) {
err = CL_MAP_FAILURE;
goto error;
}
+ ptr = (char*)ptr + offset;
+
error:
if (errcode_ret)
*errcode_ret = err;
--
1.8.1.4
More information about the Beignet
mailing list