Mesa (master): clover: Migrate a bunch of pointers and references in the object tree to smart references.

Francisco Jerez currojerez at kemper.freedesktop.org
Fri Feb 21 11:58:20 UTC 2014


Module: Mesa
Branch: master
Commit: c4578d2277155c50c8680849763850cddb8e8ec2
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=c4578d2277155c50c8680849763850cddb8e8ec2

Author: Francisco Jerez <currojerez at riseup.net>
Date:   Tue Feb 18 15:07:11 2014 +0100

clover: Migrate a bunch of pointers and references in the object tree to smart references.

Tested-by: Tom Stellard <thomas.stellard at amd.com>

---

 src/gallium/state_trackers/clover/api/event.cpp    |   12 ++---
 src/gallium/state_trackers/clover/api/kernel.cpp   |   20 ++++-----
 src/gallium/state_trackers/clover/api/memory.cpp   |    4 +-
 src/gallium/state_trackers/clover/api/program.cpp  |   20 ++++-----
 src/gallium/state_trackers/clover/api/queue.cpp    |    4 +-
 src/gallium/state_trackers/clover/api/sampler.cpp  |    2 +-
 src/gallium/state_trackers/clover/api/transfer.cpp |    8 ++--
 src/gallium/state_trackers/clover/core/context.cpp |    4 +-
 src/gallium/state_trackers/clover/core/context.hpp |    6 ++-
 src/gallium/state_trackers/clover/core/device.cpp  |    1 +
 src/gallium/state_trackers/clover/core/event.cpp   |   40 ++++++++---------
 src/gallium/state_trackers/clover/core/event.hpp   |   14 +++---
 src/gallium/state_trackers/clover/core/kernel.cpp  |   26 +++++------
 src/gallium/state_trackers/clover/core/kernel.hpp  |    8 ++--
 src/gallium/state_trackers/clover/core/memory.cpp  |   46 ++++++++++----------
 src/gallium/state_trackers/clover/core/memory.hpp  |   20 ++++-----
 .../state_trackers/clover/core/platform.cpp        |    4 +-
 .../state_trackers/clover/core/platform.hpp        |    4 +-
 src/gallium/state_trackers/clover/core/program.cpp |   17 +++++---
 src/gallium/state_trackers/clover/core/program.hpp |   12 ++---
 src/gallium/state_trackers/clover/core/queue.cpp   |   14 +++---
 src/gallium/state_trackers/clover/core/queue.hpp   |   10 ++---
 .../state_trackers/clover/core/resource.cpp        |   13 +++---
 .../state_trackers/clover/core/resource.hpp        |   11 ++---
 src/gallium/state_trackers/clover/core/sampler.cpp |    4 +-
 src/gallium/state_trackers/clover/core/sampler.hpp |    4 +-
 .../state_trackers/clover/core/timestamp.cpp       |    4 +-
 .../state_trackers/clover/core/timestamp.hpp       |    2 +-
 .../state_trackers/clover/util/functional.hpp      |    8 ++++
 29 files changed, 179 insertions(+), 163 deletions(-)

diff --git a/src/gallium/state_trackers/clover/api/event.cpp b/src/gallium/state_trackers/clover/api/event.cpp
index 05534c7..7057b77 100644
--- a/src/gallium/state_trackers/clover/api/event.cpp
+++ b/src/gallium/state_trackers/clover/api/event.cpp
@@ -63,7 +63,7 @@ clWaitForEvents(cl_uint num_evs, const cl_event *d_evs) try {
    auto evs = objs(d_evs, num_evs);
 
    for (auto &ev : evs) {
-      if (ev.ctx != evs.front().ctx)
+      if (ev.context() != evs.front().context())
          throw error(CL_INVALID_CONTEXT);
 
       if (ev.status() < 0)
@@ -73,7 +73,7 @@ clWaitForEvents(cl_uint num_evs, const cl_event *d_evs) try {
    // Create a temporary soft event that depends on all the events in
    // the wait list
    intrusive_ptr<soft_event> sev =
-      transfer(new soft_event(evs.front().ctx, evs, true));
+      transfer(new soft_event(evs.front().context(), evs, true));
 
    // ...and wait on it.
    sev->wait();
@@ -96,7 +96,7 @@ clGetEventInfo(cl_event d_ev, cl_event_info param,
       break;
 
    case CL_EVENT_CONTEXT:
-      buf.as_scalar<cl_context>() = desc(ev.ctx);
+      buf.as_scalar<cl_context>() = desc(ev.context());
       break;
 
    case CL_EVENT_COMMAND_TYPE:
@@ -133,7 +133,7 @@ clSetEventCallback(cl_event d_ev, cl_int type,
    // Create a temporary soft event that depends on ev, with
    // pfn_notify as completion action.
    intrusive_ptr<soft_event> sev = transfer(
-      new soft_event(ev.ctx, { ev }, true,
+      new soft_event(ev.context(), { ev }, true,
                      [=, &ev](event &) {
                         ev.wait();
                         pfn_notify(desc(ev), ev.status(), user_data);
@@ -199,8 +199,8 @@ clEnqueueWaitForEvents(cl_command_queue d_q, cl_uint num_evs,
    auto evs = objs(d_evs, num_evs);
 
    for (auto &ev : evs) {
-         if (ev.ctx != q.ctx)
-            throw error(CL_INVALID_CONTEXT);
+      if (ev.context() != q.context())
+         throw error(CL_INVALID_CONTEXT);
    }
 
    // Create a hard event that depends on the events in the wait list:
diff --git a/src/gallium/state_trackers/clover/api/kernel.cpp b/src/gallium/state_trackers/clover/api/kernel.cpp
index 3367363..f1a9bd8 100644
--- a/src/gallium/state_trackers/clover/api/kernel.cpp
+++ b/src/gallium/state_trackers/clover/api/kernel.cpp
@@ -125,11 +125,11 @@ clGetKernelInfo(cl_kernel d_kern, cl_kernel_info param,
       break;
 
    case CL_KERNEL_CONTEXT:
-      buf.as_scalar<cl_context>() = desc(kern.prog.ctx);
+      buf.as_scalar<cl_context>() = desc(kern.program().context());
       break;
 
    case CL_KERNEL_PROGRAM:
-      buf.as_scalar<cl_program>() = desc(kern.prog);
+      buf.as_scalar<cl_program>() = desc(kern.program());
       break;
 
    default:
@@ -148,9 +148,9 @@ clGetKernelWorkGroupInfo(cl_kernel d_kern, cl_device_id d_dev,
                          size_t size, void *r_buf, size_t *r_size) try {
    property_buffer buf { r_buf, size, r_size };
    auto &kern = obj(d_kern);
-   auto &dev = (d_dev ? *pobj(d_dev) : unique(kern.prog.devices()));
+   auto &dev = (d_dev ? *pobj(d_dev) : unique(kern.program().devices()));
 
-   if (!count(dev, kern.prog.devices()))
+   if (!count(dev, kern.program().devices()))
       throw error(CL_INVALID_DEVICE);
 
    switch (param) {
@@ -194,9 +194,9 @@ namespace {
    void
    validate_common(const command_queue &q, kernel &kern,
                    const ref_vector<event> &deps) {
-      if (kern.prog.ctx != q.ctx ||
+      if (kern.program().context() != q.context() ||
           any_of([&](const event &ev) {
-                return ev.ctx != q.ctx;
+                return ev.context() != q.context();
              }, deps))
          throw error(CL_INVALID_CONTEXT);
 
@@ -205,7 +205,7 @@ namespace {
             }, kern.args()))
          throw error(CL_INVALID_KERNEL_ARGS);
 
-      if (!count(q.dev, kern.prog.devices()))
+      if (!count(q.device(), kern.program().devices()))
          throw error(CL_INVALID_PROGRAM_EXECUTABLE);
    }
 
@@ -214,7 +214,7 @@ namespace {
                       const size_t *d_grid_size) {
       auto grid_size = range(d_grid_size, dims);
 
-      if (dims < 1 || dims > q.dev.max_block_size().size())
+      if (dims < 1 || dims > q.device().max_block_size().size())
          throw error(CL_INVALID_WORK_DIMENSION);
 
       if (!d_grid_size || any_of(is_zero(), grid_size))
@@ -242,14 +242,14 @@ namespace {
          auto block_size = range(d_block_size, dims);
 
          if (any_of(is_zero(), block_size) ||
-             any_of(greater(), block_size, q.dev.max_block_size()))
+             any_of(greater(), block_size, q.device().max_block_size()))
             throw error(CL_INVALID_WORK_ITEM_SIZE);
 
          if (any_of(modulus(), grid_size, block_size))
             throw error(CL_INVALID_WORK_GROUP_SIZE);
 
          if (fold(multiplies(), 1u, block_size) >
-             q.dev.max_threads_per_block())
+             q.device().max_threads_per_block())
             throw error(CL_INVALID_WORK_GROUP_SIZE);
 
          return block_size;
diff --git a/src/gallium/state_trackers/clover/api/memory.cpp b/src/gallium/state_trackers/clover/api/memory.cpp
index e51a729..84b3bcb 100644
--- a/src/gallium/state_trackers/clover/api/memory.cpp
+++ b/src/gallium/state_trackers/clover/api/memory.cpp
@@ -230,12 +230,12 @@ clGetMemObjectInfo(cl_mem d_mem, cl_mem_info param,
       break;
 
    case CL_MEM_CONTEXT:
-      buf.as_scalar<cl_context>() = desc(mem.ctx);
+      buf.as_scalar<cl_context>() = desc(mem.context());
       break;
 
    case CL_MEM_ASSOCIATED_MEMOBJECT: {
       sub_buffer *sub = dynamic_cast<sub_buffer *>(&mem);
-      buf.as_scalar<cl_mem>() = (sub ? desc(sub->parent) : NULL);
+      buf.as_scalar<cl_mem>() = (sub ? desc(sub->parent()) : NULL);
       break;
    }
    case CL_MEM_OFFSET: {
diff --git a/src/gallium/state_trackers/clover/api/program.cpp b/src/gallium/state_trackers/clover/api/program.cpp
index 6049209..8867ee9 100644
--- a/src/gallium/state_trackers/clover/api/program.cpp
+++ b/src/gallium/state_trackers/clover/api/program.cpp
@@ -133,7 +133,7 @@ clBuildProgram(cl_program d_prog, cl_uint num_devs,
                void *user_data) try {
    auto &prog = obj(d_prog);
    auto devs = (d_devs ? objs(d_devs, num_devs) :
-                ref_vector<device>(prog.ctx.devs()));
+                ref_vector<device>(prog.context().devs()));
    auto opts = (p_opts ? p_opts : "");
 
    if (bool(num_devs) != bool(d_devs) ||
@@ -141,7 +141,7 @@ clBuildProgram(cl_program d_prog, cl_uint num_devs,
       throw error(CL_INVALID_VALUE);
 
    if (any_of([&](const device &dev) {
-            return !count(dev, prog.ctx.devs());
+            return !count(dev, prog.context().devs());
          }, devs))
       throw error(CL_INVALID_DEVICE);
 
@@ -169,19 +169,19 @@ clGetProgramInfo(cl_program d_prog, cl_program_info param,
       break;
 
    case CL_PROGRAM_CONTEXT:
-      buf.as_scalar<cl_context>() = desc(prog.ctx);
+      buf.as_scalar<cl_context>() = desc(prog.context());
       break;
 
    case CL_PROGRAM_NUM_DEVICES:
-      buf.as_scalar<cl_uint>() = prog.devices().size() ?
-                                 prog.devices().size() :
-                                 prog.ctx.devs().size();
+      buf.as_scalar<cl_uint>() = (prog.devices().size() ?
+                                  prog.devices().size() :
+                                  prog.context().devs().size());
       break;
 
    case CL_PROGRAM_DEVICES:
-      buf.as_vector<cl_device_id>() = prog.devices().size() ?
-                                      descs(prog.devices()) :
-                                      descs(prog.ctx.devs());
+      buf.as_vector<cl_device_id>() = (prog.devices().size() ?
+                                       descs(prog.devices()) :
+                                       descs(prog.context().devs()));
       break;
 
    case CL_PROGRAM_SOURCE:
@@ -226,7 +226,7 @@ clGetProgramBuildInfo(cl_program d_prog, cl_device_id d_dev,
    auto &prog = obj(d_prog);
    auto &dev = obj(d_dev);
 
-   if (!count(dev, prog.ctx.devs()))
+   if (!count(dev, prog.context().devs()))
       return CL_INVALID_DEVICE;
 
    switch (param) {
diff --git a/src/gallium/state_trackers/clover/api/queue.cpp b/src/gallium/state_trackers/clover/api/queue.cpp
index 1c251b0..8498e97 100644
--- a/src/gallium/state_trackers/clover/api/queue.cpp
+++ b/src/gallium/state_trackers/clover/api/queue.cpp
@@ -75,11 +75,11 @@ clGetCommandQueueInfo(cl_command_queue d_q, cl_command_queue_info param,
 
    switch (param) {
    case CL_QUEUE_CONTEXT:
-      buf.as_scalar<cl_context>() = desc(q.ctx);
+      buf.as_scalar<cl_context>() = desc(q.context());
       break;
 
    case CL_QUEUE_DEVICE:
-      buf.as_scalar<cl_device_id>() = desc(q.dev);
+      buf.as_scalar<cl_device_id>() = desc(q.device());
       break;
 
    case CL_QUEUE_REFERENCE_COUNT:
diff --git a/src/gallium/state_trackers/clover/api/sampler.cpp b/src/gallium/state_trackers/clover/api/sampler.cpp
index 5a04d2b..403892b 100644
--- a/src/gallium/state_trackers/clover/api/sampler.cpp
+++ b/src/gallium/state_trackers/clover/api/sampler.cpp
@@ -71,7 +71,7 @@ clGetSamplerInfo(cl_sampler d_s, cl_sampler_info param,
       break;
 
    case CL_SAMPLER_CONTEXT:
-      buf.as_scalar<cl_context>() = desc(s.ctx);
+      buf.as_scalar<cl_context>() = desc(s.context());
       break;
 
    case CL_SAMPLER_NORMALIZED_COORDS:
diff --git a/src/gallium/state_trackers/clover/api/transfer.cpp b/src/gallium/state_trackers/clover/api/transfer.cpp
index 48717be..02d0dd0 100644
--- a/src/gallium/state_trackers/clover/api/transfer.cpp
+++ b/src/gallium/state_trackers/clover/api/transfer.cpp
@@ -24,7 +24,7 @@
 
 #include "api/util.hpp"
 #include "core/event.hpp"
-#include "core/resource.hpp"
+#include "core/memory.hpp"
 
 using namespace clover;
 
@@ -56,7 +56,7 @@ namespace {
    validate_common(command_queue &q,
                    const ref_vector<event> &deps) {
       if (any_of([&](const event &ev) {
-               return &ev.ctx != &q.ctx;
+               return ev.context() != q.context();
             }, deps))
          throw error(CL_INVALID_CONTEXT);
    }
@@ -67,7 +67,7 @@ namespace {
    void
    validate_object(command_queue &q, buffer &mem, const vector_t &origin,
                    const vector_t &pitch, const vector_t &region) {
-      if (mem.ctx != q.ctx)
+      if (mem.context() != q.context())
          throw error(CL_INVALID_CONTEXT);
 
       // The region must fit within the specified pitch,
@@ -90,7 +90,7 @@ namespace {
                    const vector_t &orig, const vector_t &region) {
       vector_t size = { img.width(), img.height(), img.depth() };
 
-      if (img.ctx != q.ctx)
+      if (img.context() != q.context())
          throw error(CL_INVALID_CONTEXT);
 
       if (any_of(greater(), orig + region, size))
diff --git a/src/gallium/state_trackers/clover/core/context.cpp b/src/gallium/state_trackers/clover/core/context.cpp
index e2658f2..34ffd9f 100644
--- a/src/gallium/state_trackers/clover/core/context.cpp
+++ b/src/gallium/state_trackers/clover/core/context.cpp
@@ -26,7 +26,7 @@ using namespace clover;
 
 context::context(const property_list &props,
                  const ref_vector<device> &devs) :
-   _props(props), _devs(map(addresses(), devs)) {
+   _props(props), _devs(devs) {
 }
 
 bool
@@ -46,5 +46,5 @@ context::props() const {
 
 context::device_range
 context::devs() const {
-   return map(derefs(), _devs);
+   return map(evals(), _devs);
 }
diff --git a/src/gallium/state_trackers/clover/core/context.hpp b/src/gallium/state_trackers/clover/core/context.hpp
index 0b5cf8a..ef14f15 100644
--- a/src/gallium/state_trackers/clover/core/context.hpp
+++ b/src/gallium/state_trackers/clover/core/context.hpp
@@ -30,7 +30,9 @@
 namespace clover {
    class context : public ref_counter, public _cl_context {
    private:
-      typedef adaptor_range<derefs, const std::vector<device *> &> device_range;
+      typedef adaptor_range<
+            evals, const std::vector<intrusive_ref<device>> &
+         > device_range;
       typedef clover::property_list<cl_context_properties> property_list;
 
    public:
@@ -53,7 +55,7 @@ namespace clover {
 
    private:
       property_list _props;
-      const std::vector<clover::device *> _devs;
+      const std::vector<intrusive_ref<device>> _devs;
    };
 }
 
diff --git a/src/gallium/state_trackers/clover/core/device.cpp b/src/gallium/state_trackers/clover/core/device.cpp
index 76a49d0..2c5f9b7 100644
--- a/src/gallium/state_trackers/clover/core/device.cpp
+++ b/src/gallium/state_trackers/clover/core/device.cpp
@@ -21,6 +21,7 @@
 //
 
 #include "core/device.hpp"
+#include "core/platform.hpp"
 #include "pipe/p_screen.h"
 #include "pipe/p_state.h"
 
diff --git a/src/gallium/state_trackers/clover/core/event.cpp b/src/gallium/state_trackers/clover/core/event.cpp
index 3f3e05e..58de888 100644
--- a/src/gallium/state_trackers/clover/core/event.cpp
+++ b/src/gallium/state_trackers/clover/core/event.cpp
@@ -25,12 +25,12 @@
 
 using namespace clover;
 
-event::event(context &ctx, const ref_vector<event> &deps,
+event::event(clover::context &ctx, const ref_vector<event> &deps,
              action action_ok, action action_fail) :
-   ctx(ctx), _status(0), wait_count(1),
+   context(ctx), _status(0), wait_count(1),
    action_ok(action_ok), action_fail(action_fail) {
    for (auto &ev : deps)
-      ev.chain(this);
+      ev.chain(*this);
 }
 
 event::~event() {
@@ -42,7 +42,7 @@ event::trigger() {
       action_ok(*this);
 
       while (!_chain.empty()) {
-         _chain.back()->trigger();
+         _chain.back()().trigger();
          _chain.pop_back();
       }
    }
@@ -54,7 +54,7 @@ event::abort(cl_int status) {
    action_fail(*this);
 
    while (!_chain.empty()) {
-      _chain.back()->abort(status);
+      _chain.back()().abort(status);
       _chain.pop_back();
    }
 }
@@ -65,33 +65,33 @@ event::signalled() const {
 }
 
 void
-event::chain(event *ev) {
+event::chain(event &ev) {
    if (wait_count) {
-      ev->wait_count++;
+      ev.wait_count++;
       _chain.push_back(ev);
    }
-   ev->deps.push_back(this);
+   ev.deps.push_back(*this);
 }
 
 hard_event::hard_event(command_queue &q, cl_command_type command,
                        const ref_vector<event> &deps, action action) :
-   event(q.ctx, deps, profile(q, action), [](event &ev){}),
+   event(q.context(), deps, profile(q, action), [](event &ev){}),
    _queue(q), _command(command), _fence(NULL) {
    if (q.profiling_enabled())
       _time_queued = timestamp::current(q);
 
-   q.sequence(this);
+   q.sequence(*this);
    trigger();
 }
 
 hard_event::~hard_event() {
-   pipe_screen *screen = queue()->dev.pipe;
+   pipe_screen *screen = queue()->device().pipe;
    screen->fence_reference(screen, &_fence, NULL);
 }
 
 cl_int
 hard_event::status() const {
-   pipe_screen *screen = queue()->dev.pipe;
+   pipe_screen *screen = queue()->device().pipe;
 
    if (_status < 0)
       return _status;
@@ -108,7 +108,7 @@ hard_event::status() const {
 
 command_queue *
 hard_event::queue() const {
-   return &_queue;
+   return &_queue();
 }
 
 cl_command_type
@@ -118,7 +118,7 @@ hard_event::command() const {
 
 void
 hard_event::wait() const {
-   pipe_screen *screen = queue()->dev.pipe;
+   pipe_screen *screen = queue()->device().pipe;
 
    if (status() == CL_QUEUED)
       queue()->flush();
@@ -150,7 +150,7 @@ hard_event::time_end() const {
 
 void
 hard_event::fence(pipe_fence_handle *fence) {
-   pipe_screen *screen = queue()->dev.pipe;
+   pipe_screen *screen = queue()->device().pipe;
    screen->fence_reference(screen, &_fence, fence);
 }
 
@@ -173,7 +173,7 @@ hard_event::profile(command_queue &q, const action &action) const {
    }
 }
 
-soft_event::soft_event(context &ctx, const ref_vector<event> &deps,
+soft_event::soft_event(clover::context &ctx, const ref_vector<event> &deps,
                        bool _trigger, action action) :
    event(ctx, deps, action, action) {
    if (_trigger)
@@ -186,8 +186,8 @@ soft_event::status() const {
       return _status;
 
    else if (!signalled() ||
-            any_of([](const intrusive_ptr<event> &ev) {
-                  return ev->status() != CL_COMPLETE;
+            any_of([](const event &ev) {
+                  return ev.status() != CL_COMPLETE;
                }, deps))
       return CL_SUBMITTED;
 
@@ -207,8 +207,8 @@ soft_event::command() const {
 
 void
 soft_event::wait() const {
-   for (auto ev : deps)
-      ev->wait();
+   for (event &ev : deps)
+      ev.wait();
 
    if (status() != CL_COMPLETE)
       throw error(CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST);
diff --git a/src/gallium/state_trackers/clover/core/event.hpp b/src/gallium/state_trackers/clover/core/event.hpp
index 123304b..0e1359a 100644
--- a/src/gallium/state_trackers/clover/core/event.hpp
+++ b/src/gallium/state_trackers/clover/core/event.hpp
@@ -53,7 +53,7 @@ namespace clover {
    public:
       typedef std::function<void (event &)> action;
 
-      event(context &ctx, const ref_vector<event> &deps,
+      event(clover::context &ctx, const ref_vector<event> &deps,
             action action_ok, action action_fail);
       virtual ~event();
 
@@ -70,19 +70,19 @@ namespace clover {
       virtual cl_command_type command() const = 0;
       virtual void wait() const = 0;
 
-      context &ctx;
+      const intrusive_ref<clover::context> context;
 
    protected:
-      void chain(event *ev);
+      void chain(event &ev);
 
       cl_int _status;
-      std::vector<intrusive_ptr<event>> deps;
+      std::vector<intrusive_ref<event>> deps;
 
    private:
       unsigned wait_count;
       action action_ok;
       action action_fail;
-      std::vector<intrusive_ptr<event>> _chain;
+      std::vector<intrusive_ref<event>> _chain;
    };
 
    ///
@@ -120,7 +120,7 @@ namespace clover {
       virtual void fence(pipe_fence_handle *fence);
       action profile(command_queue &q, const action &action) const;
 
-      command_queue &_queue;
+      const intrusive_ref<command_queue> _queue;
       cl_command_type _command;
       pipe_fence_handle *_fence;
       lazy<cl_ulong> _time_queued, _time_submit, _time_start, _time_end;
@@ -135,7 +135,7 @@ namespace clover {
    ///
    class soft_event : public event {
    public:
-      soft_event(context &ctx, const ref_vector<event> &deps,
+      soft_event(clover::context &ctx, const ref_vector<event> &deps,
                  bool trigger, action action = [](event &){});
 
       virtual cl_int status() const;
diff --git a/src/gallium/state_trackers/clover/core/kernel.cpp b/src/gallium/state_trackers/clover/core/kernel.cpp
index fa9453b..ea67e3b 100644
--- a/src/gallium/state_trackers/clover/core/kernel.cpp
+++ b/src/gallium/state_trackers/clover/core/kernel.cpp
@@ -28,9 +28,9 @@
 
 using namespace clover;
 
-kernel::kernel(program &prog, const std::string &name,
+kernel::kernel(clover::program &prog, const std::string &name,
                const std::vector<module::argument> &margs) :
-   prog(prog), _name(name), exec(*this) {
+   program(prog), _name(name), exec(*this) {
    for (auto &marg : margs) {
       if (marg.type == module::argument::scalar)
          _args.emplace_back(new scalar_argument(marg.size));
@@ -57,7 +57,7 @@ template<typename V>
 static inline std::vector<uint>
 pad_vector(command_queue &q, const V &v, uint x) {
    std::vector<uint> w { v.begin(), v.end() };
-   w.resize(q.dev.max_block_size().size(), x);
+   w.resize(q.device().max_block_size().size(), x);
    return w;
 }
 
@@ -66,7 +66,7 @@ kernel::launch(command_queue &q,
                const std::vector<size_t> &grid_offset,
                const std::vector<size_t> &grid_size,
                const std::vector<size_t> &block_size) {
-   const auto m = prog.binary(q.dev);
+   const auto m = program().binary(q.device());
    const auto reduced_grid_size =
       map(divides(), grid_size, block_size);
    void *st = exec.bind(&q);
@@ -130,7 +130,7 @@ std::vector<size_t>
 kernel::optimal_block_size(const command_queue &q,
                            const std::vector<size_t> &grid_size) const {
    return factor::find_grid_optimal_factor<size_t>(
-      q.dev.max_threads_per_block(), q.dev.max_block_size(),
+      q.device().max_threads_per_block(), q.device().max_block_size(),
       grid_size);
 }
 
@@ -151,7 +151,7 @@ kernel::args() const {
 
 const module &
 kernel::module(const command_queue &q) const {
-   return prog.binary(q.dev);
+   return program().binary(q.device());
 }
 
 kernel::exec_context::exec_context(kernel &kern) :
@@ -164,11 +164,11 @@ kernel::exec_context::~exec_context() {
 }
 
 void *
-kernel::exec_context::bind(command_queue *_q) {
+kernel::exec_context::bind(intrusive_ptr<command_queue> _q) {
    std::swap(q, _q);
 
    // Bind kernel arguments.
-   auto &m = kern.prog.binary(q->dev);
+   auto &m = kern.program().binary(q->device());
    auto margs = find(name_equals(kern.name()), m.syms).args;
    auto msec = find(type_equals(module::section::text), m.secs);
 
@@ -313,7 +313,7 @@ kernel::scalar_argument::bind(exec_context &ctx,
    auto w = v;
 
    extend(w, marg.ext_type, marg.target_size);
-   byteswap(w, ctx.q->dev.endianness());
+   byteswap(w, ctx.q->device().endianness());
    align(ctx.input, marg.target_align);
    insert(ctx.input, w);
 }
@@ -369,7 +369,7 @@ kernel::local_argument::bind(exec_context &ctx,
    auto v = bytes(ctx.mem_local);
 
    extend(v, module::argument::zero_ext, marg.target_size);
-   byteswap(v, ctx.q->dev.endianness());
+   byteswap(v, ctx.q->device().endianness());
    align(ctx.input, marg.target_align);
    insert(ctx.input, v);
 
@@ -398,7 +398,7 @@ kernel::constant_argument::bind(exec_context &ctx,
       auto v = bytes(ctx.resources.size() << 24);
 
       extend(v, module::argument::zero_ext, marg.target_size);
-      byteswap(v, ctx.q->dev.endianness());
+      byteswap(v, ctx.q->device().endianness());
       insert(ctx.input, v);
 
       st = buf->resource(*ctx.q).bind_surface(*ctx.q, false);
@@ -430,7 +430,7 @@ kernel::image_rd_argument::bind(exec_context &ctx,
    auto v = bytes(ctx.sviews.size());
 
    extend(v, module::argument::zero_ext, marg.target_size);
-   byteswap(v, ctx.q->dev.endianness());
+   byteswap(v, ctx.q->device().endianness());
    align(ctx.input, marg.target_align);
    insert(ctx.input, v);
 
@@ -458,7 +458,7 @@ kernel::image_wr_argument::bind(exec_context &ctx,
    auto v = bytes(ctx.resources.size());
 
    extend(v, module::argument::zero_ext, marg.target_size);
-   byteswap(v, ctx.q->dev.endianness());
+   byteswap(v, ctx.q->device().endianness());
    align(ctx.input, marg.target_align);
    insert(ctx.input, v);
 
diff --git a/src/gallium/state_trackers/clover/core/kernel.hpp b/src/gallium/state_trackers/clover/core/kernel.hpp
index f42e199..e544ec6 100644
--- a/src/gallium/state_trackers/clover/core/kernel.hpp
+++ b/src/gallium/state_trackers/clover/core/kernel.hpp
@@ -46,11 +46,11 @@ namespace clover {
          exec_context &
          operator=(const exec_context &) = delete;
 
-         void *bind(command_queue *q);
+         void *bind(intrusive_ptr<command_queue> _q);
          void unbind();
 
          kernel &kern;
-         command_queue *q;
+         intrusive_ptr<command_queue> q;
 
          std::vector<uint8_t> input;
          std::vector<void *> samplers;
@@ -105,7 +105,7 @@ namespace clover {
          > const_argument_range;
 
    public:
-      kernel(program &prog, const std::string &name,
+      kernel(clover::program &prog, const std::string &name,
              const std::vector<clover::module::argument> &margs);
 
       kernel(const kernel &kern) = delete;
@@ -131,7 +131,7 @@ namespace clover {
       argument_range args();
       const_argument_range args() const;
 
-      program &prog;
+      const intrusive_ref<clover::program> program;
 
    private:
       const clover::module &module(const command_queue &q) const;
diff --git a/src/gallium/state_trackers/clover/core/memory.cpp b/src/gallium/state_trackers/clover/core/memory.cpp
index 1db3f68..ba6869d 100644
--- a/src/gallium/state_trackers/clover/core/memory.cpp
+++ b/src/gallium/state_trackers/clover/core/memory.cpp
@@ -26,9 +26,9 @@
 
 using namespace clover;
 
-memory_obj::memory_obj(context &ctx, cl_mem_flags flags,
+memory_obj::memory_obj(clover::context &ctx, cl_mem_flags flags,
                        size_t size, void *host_ptr) :
-   ctx(ctx), _flags(flags),
+   context(ctx), _flags(flags),
    _size(size), _host_ptr(host_ptr),
    _destroy_notify([]{}) {
    if (flags & (CL_MEM_COPY_HOST_PTR | CL_MEM_USE_HOST_PTR))
@@ -64,7 +64,7 @@ memory_obj::host_ptr() const {
    return _host_ptr;
 }
 
-buffer::buffer(context &ctx, cl_mem_flags flags,
+buffer::buffer(clover::context &ctx, cl_mem_flags flags,
                size_t size, void *host_ptr) :
    memory_obj(ctx, flags, size, host_ptr) {
 }
@@ -74,7 +74,7 @@ buffer::type() const {
    return CL_MEM_OBJECT_BUFFER;
 }
 
-root_buffer::root_buffer(context &ctx, cl_mem_flags flags,
+root_buffer::root_buffer(clover::context &ctx, cl_mem_flags flags,
                          size_t size, void *host_ptr) :
    buffer(ctx, flags, size, host_ptr) {
 }
@@ -82,22 +82,23 @@ root_buffer::root_buffer(context &ctx, cl_mem_flags flags,
 resource &
 root_buffer::resource(command_queue &q) {
    // Create a new resource if there's none for this device yet.
-   if (!resources.count(&q.dev)) {
+   if (!resources.count(&q.device())) {
       auto r = (!resources.empty() ?
-                new root_resource(q.dev, *this, *resources.begin()->second) :
-                new root_resource(q.dev, *this, q, data));
+                new root_resource(q.device(), *this,
+                                  *resources.begin()->second) :
+                new root_resource(q.device(), *this, q, data));
 
-      resources.insert(std::make_pair(&q.dev,
+      resources.insert(std::make_pair(&q.device(),
                                       std::unique_ptr<root_resource>(r)));
       data.clear();
    }
 
-   return *resources.find(&q.dev)->second;
+   return *resources.find(&q.device())->second;
 }
 
 sub_buffer::sub_buffer(root_buffer &parent, cl_mem_flags flags,
                        size_t offset, size_t size) :
-   buffer(parent.ctx, flags, size,
+   buffer(parent.context(), flags, size,
           (char *)parent.host_ptr() + offset),
    parent(parent), _offset(offset) {
 }
@@ -105,14 +106,14 @@ sub_buffer::sub_buffer(root_buffer &parent, cl_mem_flags flags,
 resource &
 sub_buffer::resource(command_queue &q) {
    // Create a new resource if there's none for this device yet.
-   if (!resources.count(&q.dev)) {
-      auto r = new sub_resource(parent.resource(q), {{ offset() }});
+   if (!resources.count(&q.device())) {
+      auto r = new sub_resource(parent().resource(q), {{ offset() }});
 
-      resources.insert(std::make_pair(&q.dev,
+      resources.insert(std::make_pair(&q.device(),
                                       std::unique_ptr<sub_resource>(r)));
    }
 
-   return *resources.find(&q.dev)->second;
+   return *resources.find(&q.device())->second;
 }
 
 size_t
@@ -120,7 +121,7 @@ sub_buffer::offset() const {
    return _offset;
 }
 
-image::image(context &ctx, cl_mem_flags flags,
+image::image(clover::context &ctx, cl_mem_flags flags,
              const cl_image_format *format,
              size_t width, size_t height, size_t depth,
              size_t row_pitch, size_t slice_pitch, size_t size,
@@ -133,17 +134,18 @@ image::image(context &ctx, cl_mem_flags flags,
 resource &
 image::resource(command_queue &q) {
    // Create a new resource if there's none for this device yet.
-   if (!resources.count(&q.dev)) {
+   if (!resources.count(&q.device())) {
       auto r = (!resources.empty() ?
-                new root_resource(q.dev, *this, *resources.begin()->second) :
-                new root_resource(q.dev, *this, q, data));
+                new root_resource(q.device(), *this,
+                                  *resources.begin()->second) :
+                new root_resource(q.device(), *this, q, data));
 
-      resources.insert(std::make_pair(&q.dev,
+      resources.insert(std::make_pair(&q.device(),
                                       std::unique_ptr<root_resource>(r)));
       data.clear();
    }
 
-   return *resources.find(&q.dev)->second;
+   return *resources.find(&q.device())->second;
 }
 
 cl_image_format
@@ -181,7 +183,7 @@ image::slice_pitch() const {
    return _slice_pitch;
 }
 
-image2d::image2d(context &ctx, cl_mem_flags flags,
+image2d::image2d(clover::context &ctx, cl_mem_flags flags,
                  const cl_image_format *format, size_t width,
                  size_t height, size_t row_pitch,
                  void *host_ptr) :
@@ -194,7 +196,7 @@ image2d::type() const {
    return CL_MEM_OBJECT_IMAGE2D;
 }
 
-image3d::image3d(context &ctx, cl_mem_flags flags,
+image3d::image3d(clover::context &ctx, cl_mem_flags flags,
                  const cl_image_format *format,
                  size_t width, size_t height, size_t depth,
                  size_t row_pitch, size_t slice_pitch,
diff --git a/src/gallium/state_trackers/clover/core/memory.hpp b/src/gallium/state_trackers/clover/core/memory.hpp
index 6ccf3da..f649ca0 100644
--- a/src/gallium/state_trackers/clover/core/memory.hpp
+++ b/src/gallium/state_trackers/clover/core/memory.hpp
@@ -29,14 +29,12 @@
 
 #include "core/object.hpp"
 #include "core/queue.hpp"
+#include "core/resource.hpp"
 
 namespace clover {
-   class resource;
-   class sub_resource;
-
    class memory_obj : public ref_counter, public _cl_mem {
    protected:
-      memory_obj(context &ctx, cl_mem_flags flags,
+      memory_obj(clover::context &ctx, cl_mem_flags flags,
                  size_t size, void *host_ptr);
 
       memory_obj(const memory_obj &obj) = delete;
@@ -57,7 +55,7 @@ namespace clover {
       size_t size() const;
       void *host_ptr() const;
 
-      context &ctx;
+      const intrusive_ref<clover::context> context;
 
    private:
       cl_mem_flags _flags;
@@ -71,7 +69,7 @@ namespace clover {
 
    class buffer : public memory_obj {
    protected:
-      buffer(context &ctx, cl_mem_flags flags,
+      buffer(clover::context &ctx, cl_mem_flags flags,
              size_t size, void *host_ptr);
 
    public:
@@ -80,7 +78,7 @@ namespace clover {
 
    class root_buffer : public buffer {
    public:
-      root_buffer(context &ctx, cl_mem_flags flags,
+      root_buffer(clover::context &ctx, cl_mem_flags flags,
                   size_t size, void *host_ptr);
 
       virtual clover::resource &resource(command_queue &q);
@@ -98,7 +96,7 @@ namespace clover {
       virtual clover::resource &resource(command_queue &q);
       size_t offset() const;
 
-      root_buffer &parent;
+      const intrusive_ref<root_buffer> parent;
 
    private:
       size_t _offset;
@@ -108,7 +106,7 @@ namespace clover {
 
    class image : public memory_obj {
    protected:
-      image(context &ctx, cl_mem_flags flags,
+      image(clover::context &ctx, cl_mem_flags flags,
             const cl_image_format *format,
             size_t width, size_t height, size_t depth,
             size_t row_pitch, size_t slice_pitch, size_t size,
@@ -137,7 +135,7 @@ namespace clover {
 
    class image2d : public image {
    public:
-      image2d(context &ctx, cl_mem_flags flags,
+      image2d(clover::context &ctx, cl_mem_flags flags,
               const cl_image_format *format, size_t width,
               size_t height, size_t row_pitch,
               void *host_ptr);
@@ -147,7 +145,7 @@ namespace clover {
 
    class image3d : public image {
    public:
-      image3d(context &ctx, cl_mem_flags flags,
+      image3d(clover::context &ctx, cl_mem_flags flags,
               const cl_image_format *format,
               size_t width, size_t height, size_t depth,
               size_t row_pitch, size_t slice_pitch,
diff --git a/src/gallium/state_trackers/clover/core/platform.cpp b/src/gallium/state_trackers/clover/core/platform.cpp
index 762a015..0a12a61 100644
--- a/src/gallium/state_trackers/clover/core/platform.cpp
+++ b/src/gallium/state_trackers/clover/core/platform.cpp
@@ -24,7 +24,7 @@
 
 using namespace clover;
 
-platform::platform() : adaptor_range(derefs(), devs) {
+platform::platform() : adaptor_range(evals(), devs) {
    int n = pipe_loader_probe(NULL, 0);
    std::vector<pipe_loader_device *> ldevs(n);
 
@@ -32,7 +32,7 @@ platform::platform() : adaptor_range(derefs(), devs) {
 
    for (pipe_loader_device *ldev : ldevs) {
       try {
-         devs.push_back(transfer(new device(*this, ldev)));
+         devs.push_back(transfer(*new device(*this, ldev)));
       } catch (error &) {
          pipe_loader_release(&ldev, 1);
       }
diff --git a/src/gallium/state_trackers/clover/core/platform.hpp b/src/gallium/state_trackers/clover/core/platform.hpp
index bcc8e0c..e849645 100644
--- a/src/gallium/state_trackers/clover/core/platform.hpp
+++ b/src/gallium/state_trackers/clover/core/platform.hpp
@@ -32,7 +32,7 @@
 namespace clover {
    class platform : public _cl_platform_id,
                     public adaptor_range<
-      derefs, std::vector<intrusive_ptr<device>> &> {
+      evals, std::vector<intrusive_ref<device>> &> {
    public:
       platform();
 
@@ -41,7 +41,7 @@ namespace clover {
       operator=(const platform &platform) = delete;
 
    protected:
-      std::vector<intrusive_ptr<device>> devs;
+      std::vector<intrusive_ref<device>> devs;
    };
 }
 
diff --git a/src/gallium/state_trackers/clover/core/program.cpp b/src/gallium/state_trackers/clover/core/program.cpp
index fb7e8d1..3aaa652 100644
--- a/src/gallium/state_trackers/clover/core/program.cpp
+++ b/src/gallium/state_trackers/clover/core/program.cpp
@@ -25,14 +25,15 @@
 
 using namespace clover;
 
-program::program(context &ctx, const std::string &source) :
-   has_source(true), ctx(ctx), _source(source) {
+program::program(clover::context &ctx, const std::string &source) :
+   has_source(true), context(ctx), _source(source) {
 }
 
-program::program(context &ctx,
+program::program(clover::context &ctx,
                  const ref_vector<device> &devs,
                  const std::vector<module> &binaries) :
-   has_source(false), ctx(ctx) {
+   has_source(false), context(ctx),
+   _devices(devs) {
    for_each([&](device &dev, const module &bin) {
          _binaries.insert({ &dev, bin });
       },
@@ -42,6 +43,8 @@ program::program(context &ctx,
 void
 program::build(const ref_vector<device> &devs, const char *opts) {
    if (has_source) {
+      _devices = devs;
+
       for (auto &dev : devs) {
          _binaries.erase(&dev);
          _logs.erase(&dev);
@@ -71,17 +74,17 @@ program::source() const {
 
 program::device_range
 program::devices() const {
-   return map(derefs(), map(keys(), _binaries));
+   return map(evals(), _devices);
 }
 
 const module &
 program::binary(const device &dev) const {
-   return _binaries.find(const_cast<device *>(&dev))->second;
+   return _binaries.find(&dev)->second;
 }
 
 cl_build_status
 program::build_status(const device &dev) const {
-   if (_binaries.count(const_cast<device *>(&dev)))
+   if (_binaries.count(&dev))
       return CL_BUILD_SUCCESS;
    else
       return CL_BUILD_NONE;
diff --git a/src/gallium/state_trackers/clover/core/program.hpp b/src/gallium/state_trackers/clover/core/program.hpp
index d36982c..1081454 100644
--- a/src/gallium/state_trackers/clover/core/program.hpp
+++ b/src/gallium/state_trackers/clover/core/program.hpp
@@ -33,13 +33,12 @@ namespace clover {
    class program : public ref_counter, public _cl_program {
    private:
       typedef adaptor_range<
-         derefs, adaptor_range<
-             keys, const std::map<device *, module> &>> device_range;
+         evals, const std::vector<intrusive_ref<device>> &> device_range;
 
    public:
-      program(context &ctx,
+      program(clover::context &ctx,
               const std::string &source);
-      program(context &ctx,
+      program(clover::context &ctx,
               const ref_vector<device> &devs,
               const std::vector<module> &binaries);
 
@@ -61,10 +60,11 @@ namespace clover {
 
       const compat::vector<module::symbol> &symbols() const;
 
-      context &ctx;
+      const intrusive_ref<clover::context> context;
 
    private:
-      std::map<device *, module> _binaries;
+      std::vector<intrusive_ref<device>> _devices;
+      std::map<const device *, module> _binaries;
       std::map<const device *, std::string> _logs;
       std::map<const device *, std::string> _opts;
       std::string _source;
diff --git a/src/gallium/state_trackers/clover/core/queue.cpp b/src/gallium/state_trackers/clover/core/queue.cpp
index 3a8ccab..246d927 100644
--- a/src/gallium/state_trackers/clover/core/queue.cpp
+++ b/src/gallium/state_trackers/clover/core/queue.cpp
@@ -27,9 +27,9 @@
 
 using namespace clover;
 
-command_queue::command_queue(context &ctx, device &dev,
+command_queue::command_queue(clover::context &ctx, clover::device &dev,
                              cl_command_queue_properties props) :
-   ctx(ctx), dev(dev), _props(props) {
+   context(ctx), device(dev), _props(props) {
    pipe = dev.pipe->context_create(dev.pipe, NULL);
    if (!pipe)
       throw error(CL_INVALID_DEVICE);
@@ -41,15 +41,15 @@ command_queue::~command_queue() {
 
 void
 command_queue::flush() {
-   pipe_screen *screen = dev.pipe;
+   pipe_screen *screen = device().pipe;
    pipe_fence_handle *fence = NULL;
 
    if (!queued_events.empty()) {
       pipe->flush(pipe, &fence, 0);
 
       while (!queued_events.empty() &&
-             queued_events.front()->signalled()) {
-         queued_events.front()->fence(fence);
+             queued_events.front()().signalled()) {
+         queued_events.front()().fence(fence);
          queued_events.pop_front();
       }
 
@@ -68,9 +68,9 @@ command_queue::profiling_enabled() const {
 }
 
 void
-command_queue::sequence(hard_event *ev) {
+command_queue::sequence(hard_event &ev) {
    if (!queued_events.empty())
-      queued_events.back()->chain(ev);
+      queued_events.back()().chain(ev);
 
    queued_events.push_back(ev);
 }
diff --git a/src/gallium/state_trackers/clover/core/queue.hpp b/src/gallium/state_trackers/clover/core/queue.hpp
index 81b9781..19cb891 100644
--- a/src/gallium/state_trackers/clover/core/queue.hpp
+++ b/src/gallium/state_trackers/clover/core/queue.hpp
@@ -37,7 +37,7 @@ namespace clover {
 
    class command_queue : public ref_counter, public _cl_command_queue {
    public:
-      command_queue(context &ctx, device &dev,
+      command_queue(clover::context &ctx, clover::device &dev,
                     cl_command_queue_properties props);
       ~command_queue();
 
@@ -50,8 +50,8 @@ namespace clover {
       cl_command_queue_properties props() const;
       bool profiling_enabled() const;
 
-      context &ctx;
-      device &dev;
+      const intrusive_ref<clover::context> context;
+      const intrusive_ref<clover::device> device;
 
       friend class resource;
       friend class root_resource;
@@ -65,11 +65,11 @@ namespace clover {
    private:
       /// Serialize a hardware event with respect to the previous ones,
       /// and push it to the pending list.
-      void sequence(hard_event *ev);
+      void sequence(hard_event &ev);
 
       cl_command_queue_properties _props;
       pipe_context *pipe;
-      std::deque<intrusive_ptr<hard_event>> queued_events;
+      std::deque<intrusive_ref<hard_event>> queued_events;
    };
 }
 
diff --git a/src/gallium/state_trackers/clover/core/resource.cpp b/src/gallium/state_trackers/clover/core/resource.cpp
index 7e6b51f..7b8a40a 100644
--- a/src/gallium/state_trackers/clover/core/resource.cpp
+++ b/src/gallium/state_trackers/clover/core/resource.cpp
@@ -21,6 +21,7 @@
 //
 
 #include "core/resource.hpp"
+#include "core/memory.hpp"
 #include "pipe/p_screen.h"
 #include "util/u_sampler.h"
 #include "util/u_format.h"
@@ -45,8 +46,8 @@ namespace {
    };
 }
 
-resource::resource(device &dev, memory_obj &obj) :
-   dev(dev), obj(obj), pipe(NULL), offset() {
+resource::resource(clover::device &dev, memory_obj &obj) :
+   device(dev), obj(obj), pipe(NULL), offset() {
 }
 
 resource::~resource() {
@@ -113,7 +114,7 @@ resource::unbind_surface(command_queue &q, pipe_surface *st) {
    q.pipe->surface_destroy(q.pipe, st);
 }
 
-root_resource::root_resource(device &dev, memory_obj &obj,
+root_resource::root_resource(clover::device &dev, memory_obj &obj,
                              command_queue &q, const std::string &data) :
    resource(dev, obj) {
    pipe_resource info {};
@@ -150,18 +151,18 @@ root_resource::root_resource(device &dev, memory_obj &obj,
    }
 }
 
-root_resource::root_resource(device &dev, memory_obj &obj,
+root_resource::root_resource(clover::device &dev, memory_obj &obj,
                              root_resource &r) :
    resource(dev, obj) {
    assert(0); // XXX -- resource shared among dev and r.dev
 }
 
 root_resource::~root_resource() {
-   dev.pipe->resource_destroy(dev.pipe, pipe);
+   device().pipe->resource_destroy(device().pipe, pipe);
 }
 
 sub_resource::sub_resource(resource &r, const vector &offset) :
-   resource(r.dev, r.obj) {
+   resource(r.device(), r.obj) {
    this->pipe = r.pipe;
    this->offset = r.offset + offset;
 }
diff --git a/src/gallium/state_trackers/clover/core/resource.hpp b/src/gallium/state_trackers/clover/core/resource.hpp
index 7a6a3f1..9993dcb 100644
--- a/src/gallium/state_trackers/clover/core/resource.hpp
+++ b/src/gallium/state_trackers/clover/core/resource.hpp
@@ -25,11 +25,12 @@
 
 #include <list>
 
-#include "core/memory.hpp"
+#include "core/queue.hpp"
 #include "util/algebra.hpp"
 #include "pipe/p_state.h"
 
 namespace clover {
+   class memory_obj;
    class mapping;
 
    ///
@@ -54,7 +55,7 @@ namespace clover {
       void del_map(void *p);
       unsigned map_count() const;
 
-      device &dev;
+      const intrusive_ref<clover::device> device;
       memory_obj &obj;
 
       friend class sub_resource;
@@ -62,7 +63,7 @@ namespace clover {
       friend class kernel;
 
    protected:
-      resource(device &dev, memory_obj &obj);
+      resource(clover::device &dev, memory_obj &obj);
 
       pipe_sampler_view *bind_sampler_view(command_queue &q);
       void unbind_sampler_view(command_queue &q,
@@ -84,9 +85,9 @@ namespace clover {
    ///
    class root_resource : public resource {
    public:
-      root_resource(device &dev, memory_obj &obj,
+      root_resource(clover::device &dev, memory_obj &obj,
                     command_queue &q, const std::string &data);
-      root_resource(device &dev, memory_obj &obj, root_resource &r);
+      root_resource(clover::device &dev, memory_obj &obj, root_resource &r);
       virtual ~root_resource();
    };
 
diff --git a/src/gallium/state_trackers/clover/core/sampler.cpp b/src/gallium/state_trackers/clover/core/sampler.cpp
index adab96a..6f2784b 100644
--- a/src/gallium/state_trackers/clover/core/sampler.cpp
+++ b/src/gallium/state_trackers/clover/core/sampler.cpp
@@ -25,10 +25,10 @@
 
 using namespace clover;
 
-sampler::sampler(context &ctx, bool norm_mode,
+sampler::sampler(clover::context &ctx, bool norm_mode,
                  cl_addressing_mode addr_mode,
                  cl_filter_mode filter_mode) :
-   ctx(ctx), _norm_mode(norm_mode),
+   context(ctx), _norm_mode(norm_mode),
    _addr_mode(addr_mode), _filter_mode(filter_mode) {
 }
 
diff --git a/src/gallium/state_trackers/clover/core/sampler.hpp b/src/gallium/state_trackers/clover/core/sampler.hpp
index 98d9550..2632c30 100644
--- a/src/gallium/state_trackers/clover/core/sampler.hpp
+++ b/src/gallium/state_trackers/clover/core/sampler.hpp
@@ -29,7 +29,7 @@
 namespace clover {
    class sampler : public ref_counter, public _cl_sampler {
    public:
-      sampler(context &ctx, bool norm_mode,
+      sampler(clover::context &ctx, bool norm_mode,
               cl_addressing_mode addr_mode,
               cl_filter_mode filter_mode);
 
@@ -41,7 +41,7 @@ namespace clover {
       cl_addressing_mode addr_mode();
       cl_filter_mode filter_mode();
 
-      context &ctx;
+      const intrusive_ref<clover::context> context;
 
       friend class kernel;
 
diff --git a/src/gallium/state_trackers/clover/core/timestamp.cpp b/src/gallium/state_trackers/clover/core/timestamp.cpp
index ab42f24..f168d61 100644
--- a/src/gallium/state_trackers/clover/core/timestamp.cpp
+++ b/src/gallium/state_trackers/clover/core/timestamp.cpp
@@ -40,14 +40,14 @@ timestamp::query::query(query &&other) :
 
 timestamp::query::~query() {
    if (_query)
-      q.pipe->destroy_query(q.pipe, _query);
+      q().pipe->destroy_query(q().pipe, _query);
 }
 
 cl_ulong
 timestamp::query::operator()() const {
    pipe_query_result result;
 
-   if (!q.pipe->get_query_result(q.pipe, _query, false, &result))
+   if (!q().pipe->get_query_result(q().pipe, _query, false, &result))
       throw error(CL_PROFILING_INFO_NOT_AVAILABLE);
 
    return result.u64;
diff --git a/src/gallium/state_trackers/clover/core/timestamp.hpp b/src/gallium/state_trackers/clover/core/timestamp.hpp
index 11c8ef0..b4b2c83 100644
--- a/src/gallium/state_trackers/clover/core/timestamp.hpp
+++ b/src/gallium/state_trackers/clover/core/timestamp.hpp
@@ -49,7 +49,7 @@ namespace clover {
          cl_ulong operator()() const;
 
       private:
-         command_queue &q;
+         const intrusive_ref<command_queue> q;
          pipe_query *_query;
       };
 
diff --git a/src/gallium/state_trackers/clover/util/functional.hpp b/src/gallium/state_trackers/clover/util/functional.hpp
index 2d8c4c4..fb2877a 100644
--- a/src/gallium/state_trackers/clover/util/functional.hpp
+++ b/src/gallium/state_trackers/clover/util/functional.hpp
@@ -202,6 +202,14 @@ namespace clover {
       }
    };
 
+   struct evals {
+      template<typename T>
+      auto
+      operator()(T &&x) const -> decltype(x()) {
+         return x();
+      }
+   };
+
    struct derefs {
       template<typename T>
       auto




More information about the mesa-commit mailing list