diff options
-rw-r--r-- | src/gallium/state_trackers/clover/api/context.cpp | 13 | ||||
-rw-r--r-- | src/gallium/state_trackers/clover/api/util.hpp | 38 | ||||
-rw-r--r-- | src/gallium/state_trackers/clover/core/context.cpp | 7 | ||||
-rw-r--r-- | src/gallium/state_trackers/clover/core/context.hpp | 15 | ||||
-rw-r--r-- | src/gallium/state_trackers/clover/core/property.hpp | 68 |
5 files changed, 91 insertions, 50 deletions
diff --git a/src/gallium/state_trackers/clover/api/context.cpp b/src/gallium/state_trackers/clover/api/context.cpp index ca05efc2d95..98bc2141e11 100644 --- a/src/gallium/state_trackers/clover/api/context.cpp +++ b/src/gallium/state_trackers/clover/api/context.cpp @@ -22,6 +22,7 @@ #include "api/util.hpp" #include "core/context.hpp" +#include "core/platform.hpp" using namespace clover; @@ -31,19 +32,21 @@ clCreateContext(const cl_context_properties *d_props, cl_uint num_devs, void (CL_CALLBACK *pfn_notify)(const char *, const void *, size_t, void *), void *user_data, cl_int *r_errcode) try { - auto props = property_map(d_props); + auto props = obj<property_list_tag>(d_props); auto devs = objs(d_devs, num_devs); if (!pfn_notify && user_data) throw error(CL_INVALID_VALUE); - for (auto prop : props) { - if (prop.first != CL_CONTEXT_PLATFORM) + for (auto &prop : props) { + if (prop.first == CL_CONTEXT_PLATFORM) + obj(prop.second.as<cl_platform_id>()); + else throw error(CL_INVALID_PROPERTY); } ret_error(r_errcode, CL_SUCCESS); - return desc(new context(property_vector(props), devs)); + return desc(new context(props, devs)); } catch (error &e) { ret_error(r_errcode, e); @@ -116,7 +119,7 @@ clGetContextInfo(cl_context d_ctx, cl_context_info param, break; case CL_CONTEXT_PROPERTIES: - buf.as_vector<cl_context_properties>() = ctx.props(); + buf.as_vector<cl_context_properties>() = desc(ctx.props()); break; default: diff --git a/src/gallium/state_trackers/clover/api/util.hpp b/src/gallium/state_trackers/clover/api/util.hpp index c8f786e96a2..88f6548f23f 100644 --- a/src/gallium/state_trackers/clover/api/util.hpp +++ b/src/gallium/state_trackers/clover/api/util.hpp @@ -31,44 +31,6 @@ namespace clover { /// - /// Convert a NULL-terminated property list into an std::map. - /// - template<typename T> - std::map<T, T> - property_map(const T *props) { - std::map<T, T> m; - - while (props && *props) { - T key = *props++; - T value = *props++; - - if (m.count(key)) - throw clover::error(CL_INVALID_PROPERTY); - - m.insert({ key, value }); - } - - return m; - } - - /// - /// Convert an std::map into a NULL-terminated property list. - /// - template<typename T> - std::vector<T> - property_vector(const std::map<T, T> &m) { - std::vector<T> v; - - for (auto &p : m) { - v.push_back(p.first); - v.push_back(p.second); - } - - v.push_back(0); - return v; - } - - /// /// Return an error code in \a p if non-zero. /// inline void diff --git a/src/gallium/state_trackers/clover/core/context.cpp b/src/gallium/state_trackers/clover/core/context.cpp index 7293f9406f2..7b79f82547e 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 std::vector<cl_context_properties> &props, +context::context(const property_list &props, const ref_vector<device> &devs) : devs(map(addresses(), devs)), _props(props) { } @@ -35,3 +35,8 @@ bool context::has_device(device &dev) const { return std::count(devs.begin(), devs.end(), &dev); } + +const context::property_list & +context::props() const { + return _props; +} diff --git a/src/gallium/state_trackers/clover/core/context.hpp b/src/gallium/state_trackers/clover/core/context.hpp index 7ef3db9b9d3..6fda06155ea 100644 --- a/src/gallium/state_trackers/clover/core/context.hpp +++ b/src/gallium/state_trackers/clover/core/context.hpp @@ -25,24 +25,27 @@ #include "core/object.hpp" #include "core/device.hpp" +#include "core/property.hpp" namespace clover { class context : public ref_counter, public _cl_context { + private: + typedef clover::property_list<cl_context_properties> property_list; + public: - context(const std::vector<cl_context_properties> &props, - const ref_vector<device> &devs); + context(const property_list &props, const ref_vector<device> &devs); + context(const context &ctx) = delete; bool has_device(device &dev) const; - const std::vector<cl_context_properties> &props() const { - return _props; - } + const property_list & + props() const; const std::vector<device *> devs; private: - std::vector<cl_context_properties> _props; + property_list _props; }; } diff --git a/src/gallium/state_trackers/clover/core/property.hpp b/src/gallium/state_trackers/clover/core/property.hpp index f2e5f2bcd6d..7f8e17684d9 100644 --- a/src/gallium/state_trackers/clover/core/property.hpp +++ b/src/gallium/state_trackers/clover/core/property.hpp @@ -188,6 +188,74 @@ namespace clover { return *this; } }; + + template<typename T> + class property_element { + public: + property_element() : x() { + } + + property_element(T x) : x(x) { + } + + template<typename S> + S + as() const { + assert(sizeof(S) <= sizeof(T)); + return reinterpret_cast<S>(x); + } + + private: + T x; + }; + + template<typename D> + using property_list = std::map<D, property_element<D>>; + + struct property_list_tag; + + /// + /// Create a clover::property_list object from a zero-terminated + /// CL property list. + /// + template<typename T, typename D, + typename = typename std::enable_if< + std::is_same<T, property_list_tag>::value>::type> + property_list<D> + obj(const D *d_props) { + property_list<D> props; + + while (d_props && *d_props) { + auto key = *d_props++; + auto value = *d_props++; + + if (props.count(key)) + throw error(CL_INVALID_PROPERTY); + + props.insert({ key, value }); + } + + return props; + } + + /// + /// Create a zero-terminated CL property list from a + /// clover::property_list object. + /// + template<typename D> + std::vector<D> + desc(const property_list<D> &props) { + std::vector<D> d_props; + + for (auto &prop : props) { + d_props.push_back(prop.first); + d_props.push_back(prop.second.template as<D>()); + } + + d_props.push_back(0); + + return d_props; + } } #endif |