[Beignet] [PATCH] re-enable userptr with fix: CPU access after GPU finishes the rendering

Guo Yejun yejun.guo at intel.com
Tue Nov 18 00:28:29 PST 2014


1. the wait logic is integrated into function cl_mem_map/unmap_auto
2. use cl_mem_map/unmap_auto for userptr inside clEnqueueRead/WriteBuffer
3. do not use cl_buffer_subdata for userptr, use cl_mem_map/memcpy instead

Signed-off-by: Guo Yejun <yejun.guo at intel.com>
---
 CMakeLists.txt   | 13 ++++++-------
 src/cl_enqueue.c | 32 +++++++++++++++++++++++++++-----
 src/cl_mem.c     | 11 ++++++++---
 3 files changed, 41 insertions(+), 15 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3c68187..b14de96 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -121,13 +121,12 @@ IF(DRM_INTEL_FOUND)
   INCLUDE_DIRECTORIES(${DRM_INTEL_INCLUDE_DIRS})
   MESSAGE(STATUS "Looking for DRM Intel - found at ${DRM_INTEL_PREFIX} ${DRM_INTEL_VERSION}")
   #userptr support starts from 2.4.57, but 2.4.58 is the actual stable release
-  #FIXME userptr has randome fail for some cases, need further investigating.
-  #IF(DRM_INTEL_VERSION VERSION_GREATER 2.4.57)
-  #  MESSAGE(STATUS "Enable userptr support")
-  #  SET(DRM_INTEL_USERPTR "enable")
-  #ELSE(DRM_INTEL_VERSION VERSION_GREATER 2.4.57)
-  #  MESSAGE(STATUS "Disable userptr support")
-  #ENDIF(DRM_INTEL_VERSION VERSION_GREATER 2.4.57)
+  IF(DRM_INTEL_VERSION VERSION_GREATER 2.4.57)
+    MESSAGE(STATUS "Enable userptr support")
+    SET(DRM_INTEL_USERPTR "enable")
+  ELSE(DRM_INTEL_VERSION VERSION_GREATER 2.4.57)
+    MESSAGE(STATUS "Disable userptr support")
+  ENDIF(DRM_INTEL_VERSION VERSION_GREATER 2.4.57)
 ELSE(DRM_INTEL_FOUND)
   MESSAGE(FATAL_ERROR "Looking for DRM Intel (>= 2.4.52) - not found")
 ENDIF(DRM_INTEL_FOUND)
diff --git a/src/cl_enqueue.c b/src/cl_enqueue.c
index 5798e20..d51592c 100644
--- a/src/cl_enqueue.c
+++ b/src/cl_enqueue.c
@@ -40,8 +40,15 @@ cl_int cl_enqueue_read_buffer(enqueue_data* data)
     if (cl_buffer_get_subdata(mem->bo, data->offset + buffer->sub_offset,
 			       data->size, data->ptr) != 0)
       err = CL_MAP_FAILURE;
-  } else
-    memcpy(data->ptr, (char*)mem->host_ptr + data->offset + buffer->sub_offset, data->size);
+  } else {
+    void* src_ptr = cl_mem_map_auto(mem, 0);
+    if (src_ptr == NULL)
+      err = CL_MAP_FAILURE;
+    else {
+      memcpy(data->ptr, (char*)src_ptr + data->offset + buffer->sub_offset, data->size);
+      cl_mem_unmap_auto(mem);
+    }
+  }
   return err;
 }
 
@@ -99,13 +106,28 @@ error:
 
 cl_int cl_enqueue_write_buffer(enqueue_data *data)
 {
+  cl_int err = CL_SUCCESS;
   cl_mem mem = data->mem_obj;
   assert(mem->type == CL_MEM_BUFFER_TYPE ||
          mem->type == CL_MEM_SUBBUFFER_TYPE);
   struct _cl_mem_buffer* buffer = (struct _cl_mem_buffer*)mem;
 
-  return cl_buffer_subdata(mem->bo, data->offset + buffer->sub_offset,
-			   data->size, data->const_ptr);
+  if (mem->is_userptr) {
+    void* dst_ptr = cl_mem_map_auto(mem, 1);
+    if (dst_ptr == NULL)
+      err = CL_MAP_FAILURE;
+    else {
+      memcpy((char*)dst_ptr + data->offset + buffer->sub_offset, data->const_ptr, data->size);
+      cl_mem_unmap_auto(mem);
+    }
+  }
+  else {
+    if (cl_buffer_subdata(mem->bo, data->offset + buffer->sub_offset,
+			   data->size, data->const_ptr) != 0)
+      err = CL_MAP_FAILURE;
+  }
+
+  return err;
 }
 
 cl_int cl_enqueue_write_buffer_rect(enqueue_data *data)
@@ -240,7 +262,7 @@ cl_int cl_enqueue_map_buffer(enqueue_data *data)
   struct _cl_mem_buffer* buffer = (struct _cl_mem_buffer*)mem;
 
   if (mem->is_userptr)
-    ptr = mem->host_ptr;
+    ptr = cl_mem_map_auto(mem, data->write_map ? 1 : 0);
   else {
     if(data->unsync_map == 1)
       //because using unsync map in clEnqueueMapBuffer, so force use map_gtt here
diff --git a/src/cl_mem.c b/src/cl_mem.c
index 0fbd304..65f299f 100644
--- a/src/cl_mem.c
+++ b/src/cl_mem.c
@@ -1818,8 +1818,13 @@ cl_mem_map_auto(cl_mem mem, int write)
 {
   if (IS_IMAGE(mem) && cl_mem_image(mem)->tiling != CL_NO_TILE)
     return cl_mem_map_gtt(mem);
-  else
-    return cl_mem_map(mem, write);
+  else {
+    if (mem->is_userptr) {
+      cl_buffer_wait_rendering(mem->bo);
+      return mem->host_ptr;
+    }else
+      return cl_mem_map(mem, write);
+  }
 }
 
 LOCAL cl_int
@@ -1829,7 +1834,7 @@ cl_mem_unmap_auto(cl_mem mem)
     cl_buffer_unmap_gtt(mem->bo);
     mem->mapped_gtt = 0;
   }
-  else
+  else if (!mem->is_userptr)
     cl_buffer_unmap(mem->bo);
   return CL_SUCCESS;
 }
-- 
1.9.1



More information about the Beignet mailing list