From e5fc61fa3f4ef7e00d66003b7f0298f7e20b2cc3 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Mon, 16 Sep 2013 21:13:47 -0700 Subject: clover: Add property list helpers with a syntax consistent with other API objects. Tested-by: Tom Stellard --- src/gallium/state_trackers/clover/api/context.cpp | 13 +++-- src/gallium/state_trackers/clover/api/util.hpp | 38 ------------ src/gallium/state_trackers/clover/core/context.cpp | 7 ++- src/gallium/state_trackers/clover/core/context.hpp | 15 +++-- .../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(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()); + 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() = ctx.props(); + buf.as_vector() = 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 @@ -30,44 +30,6 @@ #include "util/algorithm.hpp" namespace clover { - /// - /// Convert a NULL-terminated property list into an std::map. - /// - template - std::map - property_map(const T *props) { - std::map 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 - std::vector - property_vector(const std::map &m) { - std::vector 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. /// 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 &props, +context::context(const property_list &props, const ref_vector &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 property_list; + public: - context(const std::vector &props, - const ref_vector &devs); + context(const property_list &props, const ref_vector &devs); + context(const context &ctx) = delete; bool has_device(device &dev) const; - const std::vector &props() const { - return _props; - } + const property_list & + props() const; const std::vector devs; private: - std::vector _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 + class property_element { + public: + property_element() : x() { + } + + property_element(T x) : x(x) { + } + + template + S + as() const { + assert(sizeof(S) <= sizeof(T)); + return reinterpret_cast(x); + } + + private: + T x; + }; + + template + using property_list = std::map>; + + struct property_list_tag; + + /// + /// Create a clover::property_list object from a zero-terminated + /// CL property list. + /// + template::value>::type> + property_list + obj(const D *d_props) { + property_list 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 + std::vector + desc(const property_list &props) { + std::vector d_props; + + for (auto &prop : props) { + d_props.push_back(prop.first); + d_props.push_back(prop.second.template as()); + } + + d_props.push_back(0); + + return d_props; + } } #endif -- cgit v1.2.3