summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrancisco Jerez <currojerez@riseup.net>2013-07-21 01:06:13 +0200
committerFrancisco Jerez <currojerez@riseup.net>2013-07-21 19:13:40 +0200
commitda46fa90196228afce7b8ff14e7fcf3c33177ac0 (patch)
tree05a5ff6a5dad67a631252a2799de86772a7f5bdb
parent734b340bf963641c49b4cad8f4483c0996bfb559 (diff)
clover: Byte-swap kernel arguments when host and device endianness differ.
-rw-r--r--src/gallium/state_trackers/clover/core/kernel.cpp98
1 files changed, 61 insertions, 37 deletions
diff --git a/src/gallium/state_trackers/clover/core/kernel.cpp b/src/gallium/state_trackers/clover/core/kernel.cpp
index 9e7c088e713..fc4690c0133 100644
--- a/src/gallium/state_trackers/clover/core/kernel.cpp
+++ b/src/gallium/state_trackers/clover/core/kernel.cpp
@@ -179,6 +179,41 @@ _cl_kernel::exec_context::unbind() {
mem_local = 0;
}
+namespace {
+#if defined(PIPE_ARCH_BIG_ENDIAN)
+ const pipe_endian native_endianness = PIPE_ENDIAN_BIG;
+#elif defined(PIPE_ARCH_LITTLE_ENDIAN)
+ const pipe_endian native_endianness = PIPE_ENDIAN_LITTLE;
+#endif
+
+ template<typename T>
+ std::vector<uint8_t>
+ bytes(const T& x) {
+ return { (uint8_t *)&x, (uint8_t *)&x + sizeof(x) };
+ }
+
+ template<typename T>
+ void
+ byteswap(T &v, pipe_endian endianness) {
+ if (endianness != native_endianness)
+ std::reverse(v.begin(), v.end());
+ }
+
+ template<typename T>
+ void
+ insert(T &d, const T &s) {
+ d.insert(d.end(), s.begin(), s.end());
+ }
+
+ template<typename T>
+ size_t
+ allocate(T &d, size_t n) {
+ size_t pos = d.size();
+ d.resize(pos + n);
+ return pos;
+ }
+}
+
_cl_kernel::argument::argument() : __set(false) {
}
@@ -207,7 +242,10 @@ _cl_kernel::scalar_argument::set(size_t size, const void *value) {
void
_cl_kernel::scalar_argument::bind(exec_context &ctx,
const clover::module::argument &marg) {
- ctx.input.insert(ctx.input.end(), v.begin(), v.end());
+ auto w = v;
+
+ byteswap(w, ctx.q->dev.endianness());
+ insert(ctx.input, w);
}
void
@@ -229,16 +267,8 @@ _cl_kernel::global_argument::set(size_t size, const void *value) {
void
_cl_kernel::global_argument::bind(exec_context &ctx,
const clover::module::argument &marg) {
- size_t offset = ctx.input.size();
- size_t idx = ctx.g_buffers.size();
-
- ctx.input.resize(offset + marg.size);
-
- ctx.g_buffers.resize(idx + 1);
- ctx.g_buffers[idx] = obj->resource(ctx.q).pipe;
-
- ctx.g_handles.resize(idx + 1);
- ctx.g_handles[idx] = offset;
+ ctx.g_handles.push_back(allocate(ctx.input, marg.size));
+ ctx.g_buffers.push_back(obj->resource(ctx.q).pipe);
}
void
@@ -262,11 +292,10 @@ _cl_kernel::local_argument::set(size_t size, const void *value) {
void
_cl_kernel::local_argument::bind(exec_context &ctx,
const clover::module::argument &marg) {
- size_t offset = ctx.input.size();
- size_t ptr = ctx.mem_local;
+ auto v = bytes(ctx.mem_local);
- ctx.input.resize(offset + sizeof(uint32_t));
- *(uint32_t *)&ctx.input[offset] = ptr;
+ byteswap(v, ctx.q->dev.endianness());
+ insert(ctx.input, v);
ctx.mem_local += __storage;
}
@@ -290,14 +319,13 @@ _cl_kernel::constant_argument::set(size_t size, const void *value) {
void
_cl_kernel::constant_argument::bind(exec_context &ctx,
const clover::module::argument &marg) {
- size_t offset = ctx.input.size();
- size_t idx = ctx.resources.size();
+ auto v = bytes(ctx.resources.size() << 24);
- ctx.input.resize(offset + sizeof(uint32_t));
- *(uint32_t *)&ctx.input[offset] = idx << 24;
+ byteswap(v, ctx.q->dev.endianness());
+ insert(ctx.input, v);
- ctx.resources.resize(idx + 1);
- ctx.resources[idx] = st = obj->resource(ctx.q).bind_surface(*ctx.q, false);
+ st = obj->resource(ctx.q).bind_surface(*ctx.q, false);
+ ctx.resources.push_back(st);
}
void
@@ -320,14 +348,13 @@ _cl_kernel::image_rd_argument::set(size_t size, const void *value) {
void
_cl_kernel::image_rd_argument::bind(exec_context &ctx,
const clover::module::argument &marg) {
- size_t offset = ctx.input.size();
- size_t idx = ctx.sviews.size();
+ auto v = bytes(ctx.sviews.size());
- ctx.input.resize(offset + sizeof(uint32_t));
- *(uint32_t *)&ctx.input[offset] = idx;
+ byteswap(v, ctx.q->dev.endianness());
+ insert(ctx.input, v);
- ctx.sviews.resize(idx + 1);
- ctx.sviews[idx] = st = obj->resource(ctx.q).bind_sampler_view(*ctx.q);
+ st = obj->resource(ctx.q).bind_sampler_view(*ctx.q);
+ ctx.sviews.push_back(st);
}
void
@@ -350,14 +377,13 @@ _cl_kernel::image_wr_argument::set(size_t size, const void *value) {
void
_cl_kernel::image_wr_argument::bind(exec_context &ctx,
const clover::module::argument &marg) {
- size_t offset = ctx.input.size();
- size_t idx = ctx.resources.size();
+ auto v = bytes(ctx.resources.size());
- ctx.input.resize(offset + sizeof(uint32_t));
- *(uint32_t *)&ctx.input[offset] = idx;
+ byteswap(v, ctx.q->dev.endianness());
+ insert(ctx.input, v);
- ctx.resources.resize(idx + 1);
- ctx.resources[idx] = st = obj->resource(ctx.q).bind_surface(*ctx.q, true);
+ st = obj->resource(ctx.q).bind_surface(*ctx.q, true);
+ ctx.resources.push_back(st);
}
void
@@ -377,10 +403,8 @@ _cl_kernel::sampler_argument::set(size_t size, const void *value) {
void
_cl_kernel::sampler_argument::bind(exec_context &ctx,
const clover::module::argument &marg) {
- size_t idx = ctx.samplers.size();
-
- ctx.samplers.resize(idx + 1);
- ctx.samplers[idx] = st = obj->bind(*ctx.q);
+ st = obj->bind(*ctx.q);
+ ctx.samplers.push_back(st);
}
void