[Mesa-dev] [PATCH 1/2] clover: clEnqueueMigrateMemObjects (device)

Serge Martin edb+mesa at sigluy.net
Sat Sep 12 12:08:21 PDT 2015


implement memory objects migration to device
---
 src/gallium/state_trackers/clover/api/transfer.cpp | 48 ++++++++++++++++++----
 src/gallium/state_trackers/clover/core/memory.cpp  | 10 ++---
 src/gallium/state_trackers/clover/core/memory.hpp  | 12 ++++--
 .../state_trackers/clover/core/resource.cpp        |  6 ++-
 .../state_trackers/clover/core/resource.hpp        |  3 +-
 5 files changed, 58 insertions(+), 21 deletions(-)

diff --git a/src/gallium/state_trackers/clover/api/transfer.cpp b/src/gallium/state_trackers/clover/api/transfer.cpp
index f704625..55bab60 100644
--- a/src/gallium/state_trackers/clover/api/transfer.cpp
+++ b/src/gallium/state_trackers/clover/api/transfer.cpp
@@ -728,13 +728,43 @@ clEnqueueUnmapMemObject(cl_command_queue d_q, cl_mem d_mem, void *ptr,
 }
 
 CLOVER_API cl_int
-clEnqueueMigrateMemObjects(cl_command_queue command_queue,
-                           cl_uint num_mem_objects,
-                           const cl_mem *mem_objects,
-                           cl_mem_migration_flags flags,
-                           cl_uint num_events_in_wait_list,
-                           const cl_event *event_wait_list,
-                           cl_event *event) {
-   CLOVER_NOT_SUPPORTED_UNTIL("1.2");
-   return CL_INVALID_VALUE;
+clEnqueueMigrateMemObjects(cl_command_queue d_q, cl_uint num_mems,
+                           const cl_mem *d_mems, cl_mem_migration_flags flags,
+                           cl_uint num_deps, const cl_event *d_deps,
+                           cl_event *rd_ev) try {
+   auto &q = obj(d_q);
+   auto mems = objs(d_mems, num_mems);
+   auto deps = objs<wait_list_tag>(d_deps, num_deps);
+
+   validate_common(q, deps);
+
+	if (any_of([&](const memory_obj &m) {
+      return m.context() != q.context();
+         }, mems))
+      throw error(CL_INVALID_CONTEXT);
+
+   if (flags &&
+       (flags & ~(CL_MIGRATE_MEM_OBJECT_HOST |
+                  CL_MIGRATE_MEM_OBJECT_CONTENT_UNDEFINED)))
+      throw error(CL_INVALID_VALUE);
+
+   const bool copy_data = !(flags & CL_MIGRATE_MEM_OBJECT_CONTENT_UNDEFINED);
+
+   event::action act = [](event &){};
+   if (flags & CL_MIGRATE_MEM_OBJECT_HOST) {
+      // XXX -- remove from the device
+   } else {
+      act = [=, &q](event &) {
+               for (auto &mem : mems)
+                  mem.resource(q, copy_data);
+            };
+   }
+
+   ret_object(rd_ev,
+         create<hard_event>(q, CL_COMMAND_MIGRATE_MEM_OBJECTS, deps, act));
+
+   return CL_SUCCESS;
+
+} catch (error &e) {
+   return e.get();
 }
diff --git a/src/gallium/state_trackers/clover/core/memory.cpp b/src/gallium/state_trackers/clover/core/memory.cpp
index b852e68..47e31a3 100644
--- a/src/gallium/state_trackers/clover/core/memory.cpp
+++ b/src/gallium/state_trackers/clover/core/memory.cpp
@@ -82,13 +82,13 @@ root_buffer::root_buffer(clover::context &ctx, cl_mem_flags flags,
 }
 
 resource &
-root_buffer::resource(command_queue &q) {
+root_buffer::resource(command_queue &q, bool copy_data) {
    // Create a new resource if there's none for this device yet.
    if (!resources.count(&q.device())) {
       auto r = (!resources.empty() ?
                 new root_resource(q.device(), *this,
                                   *resources.begin()->second) :
-                new root_resource(q.device(), *this, q, data));
+                new root_resource(q.device(), *this, q, copy_data, data));
 
       resources.insert(std::make_pair(&q.device(),
                                       std::unique_ptr<root_resource>(r)));
@@ -106,7 +106,7 @@ sub_buffer::sub_buffer(root_buffer &parent, cl_mem_flags flags,
 }
 
 resource &
-sub_buffer::resource(command_queue &q) {
+sub_buffer::resource(command_queue &q, bool copy_data) {
    // Create a new resource if there's none for this device yet.
    if (!resources.count(&q.device())) {
       auto r = new sub_resource(parent().resource(q), {{ offset() }});
@@ -134,13 +134,13 @@ image::image(clover::context &ctx, cl_mem_flags flags,
 }
 
 resource &
-image::resource(command_queue &q) {
+image::resource(command_queue &q, bool copy_data) {
    // Create a new resource if there's none for this device yet.
    if (!resources.count(&q.device())) {
       auto r = (!resources.empty() ?
                 new root_resource(q.device(), *this,
                                   *resources.begin()->second) :
-                new root_resource(q.device(), *this, q, data));
+                new root_resource(q.device(), *this, q, copy_data, data));
 
       resources.insert(std::make_pair(&q.device(),
                                       std::unique_ptr<root_resource>(r)));
diff --git a/src/gallium/state_trackers/clover/core/memory.hpp b/src/gallium/state_trackers/clover/core/memory.hpp
index bd6da6b..b3a91d2 100644
--- a/src/gallium/state_trackers/clover/core/memory.hpp
+++ b/src/gallium/state_trackers/clover/core/memory.hpp
@@ -49,7 +49,8 @@ namespace clover {
       operator==(const memory_obj &obj) const;
 
       virtual cl_mem_object_type type() const = 0;
-      virtual clover::resource &resource(command_queue &q) = 0;
+      virtual clover::resource &resource(command_queue &q,
+                                         bool copy_data = true) = 0;
 
       void destroy_notify(std::function<void ()> f);
       cl_mem_flags flags() const;
@@ -82,7 +83,8 @@ namespace clover {
       root_buffer(clover::context &ctx, cl_mem_flags flags,
                   size_t size, void *host_ptr);
 
-      virtual clover::resource &resource(command_queue &q);
+      virtual clover::resource &resource(command_queue &q,
+                                         bool copy_data = true);
 
    private:
       std::map<device *,
@@ -94,7 +96,8 @@ namespace clover {
       sub_buffer(root_buffer &parent, cl_mem_flags flags,
                  size_t offset, size_t size);
 
-      virtual clover::resource &resource(command_queue &q);
+      virtual clover::resource &resource(command_queue &q,
+                                         bool copy_data = true);
       size_t offset() const;
 
       const intrusive_ref<root_buffer> parent;
@@ -114,7 +117,8 @@ namespace clover {
             void *host_ptr);
 
    public:
-      virtual clover::resource &resource(command_queue &q);
+      virtual clover::resource &resource(command_queue &q,
+                                         bool copy_data = true);
       cl_image_format format() const;
       size_t width() const;
       size_t height() const;
diff --git a/src/gallium/state_trackers/clover/core/resource.cpp b/src/gallium/state_trackers/clover/core/resource.cpp
index 10a29a9..4346064 100644
--- a/src/gallium/state_trackers/clover/core/resource.cpp
+++ b/src/gallium/state_trackers/clover/core/resource.cpp
@@ -115,7 +115,8 @@ resource::unbind_surface(command_queue &q, pipe_surface *st) {
 }
 
 root_resource::root_resource(clover::device &dev, memory_obj &obj,
-                             command_queue &q, const std::string &data) :
+                             command_queue &q,
+                             bool copy_data, const std::string &data) :
    resource(dev, obj) {
    pipe_resource info {};
    const bool user_ptr_support = dev.pipe->get_param(dev.pipe,
@@ -156,7 +157,8 @@ root_resource::root_resource(clover::device &dev, memory_obj &obj,
    if (!pipe)
       throw error(CL_OUT_OF_RESOURCES);
 
-   if (obj.flags() & (CL_MEM_USE_HOST_PTR | CL_MEM_COPY_HOST_PTR)) {
+   if (copy_data &&
+       (obj.flags() & (CL_MEM_USE_HOST_PTR | CL_MEM_COPY_HOST_PTR))) {
       const void *data_ptr = !data.empty() ? data.data() : obj.host_ptr();
       box rect { {{ 0, 0, 0 }}, {{ info.width0, info.height0, info.depth0 }} };
       unsigned cpp = util_format_get_blocksize(info.format);
diff --git a/src/gallium/state_trackers/clover/core/resource.hpp b/src/gallium/state_trackers/clover/core/resource.hpp
index 9993dcb..a3839c6 100644
--- a/src/gallium/state_trackers/clover/core/resource.hpp
+++ b/src/gallium/state_trackers/clover/core/resource.hpp
@@ -86,7 +86,8 @@ namespace clover {
    class root_resource : public resource {
    public:
       root_resource(clover::device &dev, memory_obj &obj,
-                    command_queue &q, const std::string &data);
+                    command_queue &q,
+                    bool copy_data, const std::string &data);
       root_resource(clover::device &dev, memory_obj &obj, root_resource &r);
       virtual ~root_resource();
    };
-- 
2.5.0



More information about the mesa-dev mailing list