summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/gallium/state_trackers/clover/api/context.cpp13
-rw-r--r--src/gallium/state_trackers/clover/api/util.hpp38
-rw-r--r--src/gallium/state_trackers/clover/core/context.cpp7
-rw-r--r--src/gallium/state_trackers/clover/core/context.hpp15
-rw-r--r--src/gallium/state_trackers/clover/core/property.hpp68
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