summaryrefslogtreecommitdiffstats
path: root/src/gallium/state_trackers/clover
diff options
context:
space:
mode:
authorFrancisco Jerez <[email protected]>2014-10-08 17:39:35 +0300
committerFrancisco Jerez <[email protected]>2014-10-12 01:44:19 +0300
commitbf89a97748748592639087e8167e29c98c740d33 (patch)
tree33ee8134467f84c62234422d8455e3309014fb61 /src/gallium/state_trackers/clover
parent06139c56fa070f84a931a4ddbdb894c9e8d24f55 (diff)
clover: Pass execution dimensions and offset to the kernel as implicit arguments.
Reviewed-by: Jan Vesely <[email protected]>
Diffstat (limited to 'src/gallium/state_trackers/clover')
-rw-r--r--src/gallium/state_trackers/clover/core/kernel.cpp87
-rw-r--r--src/gallium/state_trackers/clover/core/kernel.hpp8
2 files changed, 70 insertions, 25 deletions
diff --git a/src/gallium/state_trackers/clover/core/kernel.cpp b/src/gallium/state_trackers/clover/core/kernel.cpp
index e4b2152e4ab..947e785903e 100644
--- a/src/gallium/state_trackers/clover/core/kernel.cpp
+++ b/src/gallium/state_trackers/clover/core/kernel.cpp
@@ -33,24 +33,8 @@ kernel::kernel(clover::program &prog, const std::string &name,
program(prog), _name(name), exec(*this),
program_ref(prog._kernel_ref_counter) {
for (auto &marg : margs) {
- if (marg.type == module::argument::scalar)
- _args.emplace_back(new scalar_argument(marg.size));
- else if (marg.type == module::argument::global)
- _args.emplace_back(new global_argument);
- else if (marg.type == module::argument::local)
- _args.emplace_back(new local_argument);
- else if (marg.type == module::argument::constant)
- _args.emplace_back(new constant_argument);
- else if (marg.type == module::argument::image2d_rd ||
- marg.type == module::argument::image3d_rd)
- _args.emplace_back(new image_rd_argument);
- else if (marg.type == module::argument::image2d_wr ||
- marg.type == module::argument::image3d_wr)
- _args.emplace_back(new image_wr_argument);
- else if (marg.type == module::argument::sampler)
- _args.emplace_back(new sampler_argument);
- else
- throw error(CL_INVALID_KERNEL_DEFINITION);
+ if (marg.semantic == module::argument::general)
+ _args.emplace_back(argument::create(marg));
}
}
@@ -70,7 +54,7 @@ kernel::launch(command_queue &q,
const auto m = program().binary(q.device());
const auto reduced_grid_size =
map(divides(), grid_size, block_size);
- void *st = exec.bind(&q);
+ void *st = exec.bind(&q, grid_offset);
// The handles are created during exec_context::bind(), so we need make
// sure to call exec_context::bind() before retrieving them.
@@ -165,17 +149,38 @@ kernel::exec_context::~exec_context() {
}
void *
-kernel::exec_context::bind(intrusive_ptr<command_queue> _q) {
+kernel::exec_context::bind(intrusive_ptr<command_queue> _q,
+ const std::vector<size_t> &grid_offset) {
std::swap(q, _q);
// Bind kernel arguments.
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);
+ auto explicit_arg = kern._args.begin();
- for_each([=](kernel::argument &karg, const module::argument &marg) {
- karg.bind(*this, marg);
- }, kern.args(), margs);
+ for (auto &marg : margs) {
+ switch (marg.semantic) {
+ case module::argument::general:
+ (*(explicit_arg++))->bind(*this, marg);
+
+ case module::argument::grid_dimension: {
+ const cl_uint dimension = grid_offset.size();
+ auto arg = argument::create(marg);
+
+ arg->set(sizeof(dimension), &dimension);
+ arg->bind(*this, marg);
+ }
+ case module::argument::grid_offset: {
+ for (cl_uint x : pad_vector(*q, grid_offset, 1)) {
+ auto arg = argument::create(marg);
+
+ arg->set(sizeof(x), &x);
+ arg->bind(*this, marg);
+ }
+ }
+ }
+ }
// Create a new compute state if anything changed.
if (!st || q != _q ||
@@ -283,6 +288,42 @@ namespace {
}
}
+std::unique_ptr<kernel::argument>
+kernel::argument::create(const module::argument &marg) {
+ if (marg.type == module::argument::scalar)
+ return std::unique_ptr<kernel::argument>(
+ new scalar_argument(marg.size));
+
+ else if (marg.type == module::argument::global)
+ return std::unique_ptr<kernel::argument>(
+ new global_argument);
+
+ else if (marg.type == module::argument::local)
+ return std::unique_ptr<kernel::argument>(
+ new local_argument);
+
+ else if (marg.type == module::argument::constant)
+ return std::unique_ptr<kernel::argument>(
+ new constant_argument);
+
+ else if (marg.type == module::argument::image2d_rd ||
+ marg.type == module::argument::image3d_rd)
+ return std::unique_ptr<kernel::argument>(
+ new image_rd_argument);
+
+ else if (marg.type == module::argument::image2d_wr ||
+ marg.type == module::argument::image3d_wr)
+ return std::unique_ptr<kernel::argument>(
+ new image_wr_argument);
+
+ else if (marg.type == module::argument::sampler)
+ return std::unique_ptr<kernel::argument>(
+ new sampler_argument);
+
+ else
+ throw error(CL_INVALID_KERNEL_DEFINITION);
+}
+
kernel::argument::argument() : _set(false) {
}
diff --git a/src/gallium/state_trackers/clover/core/kernel.hpp b/src/gallium/state_trackers/clover/core/kernel.hpp
index f9e2765ee36..bf5998de825 100644
--- a/src/gallium/state_trackers/clover/core/kernel.hpp
+++ b/src/gallium/state_trackers/clover/core/kernel.hpp
@@ -46,7 +46,8 @@ namespace clover {
exec_context &
operator=(const exec_context &) = delete;
- void *bind(intrusive_ptr<command_queue> _q);
+ void *bind(intrusive_ptr<command_queue> _q,
+ const std::vector<size_t> &grid_offset);
void unbind();
kernel &kern;
@@ -68,7 +69,8 @@ namespace clover {
public:
class argument {
public:
- argument();
+ static std::unique_ptr<argument>
+ create(const module::argument &marg);
argument(const argument &arg) = delete;
argument &
@@ -92,6 +94,8 @@ namespace clover {
virtual void unbind(exec_context &ctx) = 0;
protected:
+ argument();
+
bool _set;
};