_cl_kernel::_cl_kernel(clover::program &prog,
const std::string &name,
- const std::vector<clover::module::argument> &args) :
+ const std::vector<clover::module::argument> &margs) :
prog(prog), __name(name), exec(*this) {
- for (auto arg : args) {
- if (arg.type == module::argument::scalar)
- this->args.emplace_back(new scalar_argument(arg.size));
- else if (arg.type == module::argument::global)
- this->args.emplace_back(new global_argument(arg.size));
- else if (arg.type == module::argument::local)
- this->args.emplace_back(new local_argument());
- else if (arg.type == module::argument::constant)
- this->args.emplace_back(new constant_argument());
- else if (arg.type == module::argument::image2d_rd ||
- arg.type == module::argument::image3d_rd)
- this->args.emplace_back(new image_rd_argument());
- else if (arg.type == module::argument::image2d_wr ||
- arg.type == module::argument::image3d_wr)
- this->args.emplace_back(new image_wr_argument());
- else if (arg.type == module::argument::sampler)
- this->args.emplace_back(new sampler_argument());
+ 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);
}
return prog.binaries().find(&q.dev)->second;
}
-
_cl_kernel::exec_context::exec_context(clover::kernel &kern) :
kern(kern), q(NULL), mem_local(0), st(NULL) {
}
_cl_kernel::exec_context::bind(clover::command_queue *__q) {
std::swap(q, __q);
- for (auto &arg : kern.args)
- arg->bind(*this);
+ // Bind kernel arguments.
+ auto margs = kern.module(*q).sym(kern.name()).args;
+ for_each([=](std::unique_ptr<kernel::argument> &karg,
+ const module::argument &marg) {
+ karg->bind(*this, marg);
+ }, kern.args.begin(), kern.args.end(), margs.begin());
// Create a new compute state if anything changed.
if (!st || q != __q ||
mem_local = 0;
}
-_cl_kernel::argument::argument(size_t size) :
- __size(size), __set(false) {
+_cl_kernel::argument::argument() : __set(false) {
}
bool
return 0;
}
-_cl_kernel::scalar_argument::scalar_argument(size_t size) :
- argument(size) {
+_cl_kernel::scalar_argument::scalar_argument(size_t size) : size(size) {
}
void
_cl_kernel::scalar_argument::set(size_t size, const void *value) {
- if (size != __size)
+ if (size != this->size)
throw error(CL_INVALID_ARG_SIZE);
v = { (uint8_t *)value, (uint8_t *)value + size };
}
void
-_cl_kernel::scalar_argument::bind(exec_context &ctx) {
+_cl_kernel::scalar_argument::bind(exec_context &ctx,
+ const clover::module::argument &marg) {
ctx.input.insert(ctx.input.end(), v.begin(), v.end());
}
_cl_kernel::scalar_argument::unbind(exec_context &ctx) {
}
-_cl_kernel::global_argument::global_argument(size_t size) :
- argument(size) {
-}
-
void
_cl_kernel::global_argument::set(size_t size, const void *value) {
if (size != sizeof(cl_mem))
}
void
-_cl_kernel::global_argument::bind(exec_context &ctx) {
+_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 + __size);
+ ctx.input.resize(offset + marg.size);
ctx.g_buffers.resize(idx + 1);
ctx.g_buffers[idx] = obj->resource(ctx.q).pipe;
_cl_kernel::global_argument::unbind(exec_context &ctx) {
}
-_cl_kernel::local_argument::local_argument() :
- argument(sizeof(uint32_t)) {
-}
-
size_t
_cl_kernel::local_argument::storage() const {
return __storage;
}
void
-_cl_kernel::local_argument::bind(exec_context &ctx) {
+_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;
_cl_kernel::local_argument::unbind(exec_context &ctx) {
}
-_cl_kernel::constant_argument::constant_argument() :
- argument(sizeof(uint32_t)) {
-}
-
void
_cl_kernel::constant_argument::set(size_t size, const void *value) {
if (size != sizeof(cl_mem))
}
void
-_cl_kernel::constant_argument::bind(exec_context &ctx) {
+_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();
obj->resource(ctx.q).unbind_surface(*ctx.q, st);
}
-_cl_kernel::image_rd_argument::image_rd_argument() :
- argument(sizeof(uint32_t)) {
-}
-
void
_cl_kernel::image_rd_argument::set(size_t size, const void *value) {
if (size != sizeof(cl_mem))
}
void
-_cl_kernel::image_rd_argument::bind(exec_context &ctx) {
+_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();
obj->resource(ctx.q).unbind_sampler_view(*ctx.q, st);
}
-_cl_kernel::image_wr_argument::image_wr_argument() :
- argument(sizeof(uint32_t)) {
-}
-
void
_cl_kernel::image_wr_argument::set(size_t size, const void *value) {
if (size != sizeof(cl_mem))
}
void
-_cl_kernel::image_wr_argument::bind(exec_context &ctx) {
+_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();
obj->resource(ctx.q).unbind_surface(*ctx.q, st);
}
-_cl_kernel::sampler_argument::sampler_argument() :
- argument(0) {
-}
-
void
_cl_kernel::sampler_argument::set(size_t size, const void *value) {
if (size != sizeof(cl_sampler))
}
void
-_cl_kernel::sampler_argument::bind(exec_context &ctx) {
+_cl_kernel::sampler_argument::bind(exec_context &ctx,
+ const clover::module::argument &marg) {
size_t idx = ctx.samplers.size();
ctx.samplers.resize(idx + 1);
public:
class argument {
public:
- argument(size_t size);
+ argument();
/// \a true if the argument has been set.
bool set() const;
- /// Argument size in the input buffer.
- size_t size() const;
-
/// Storage space required for the referenced object.
virtual size_t storage() const;
/// Allocate the necessary resources to bind the specified
/// object to this argument, and update \a ctx accordingly.
- virtual void bind(exec_context &ctx) = 0;
+ virtual void bind(exec_context &ctx,
+ const clover::module::argument &marg) = 0;
/// Free any resources that were allocated in bind().
virtual void unbind(exec_context &ctx) = 0;
protected:
- size_t __size;
bool __set;
};
_cl_kernel(clover::program &prog,
const std::string &name,
- const std::vector<clover::module::argument> &args);
+ const std::vector<clover::module::argument> &margs);
void launch(clover::command_queue &q,
const std::vector<size_t> &grid_offset,
scalar_argument(size_t size);
virtual void set(size_t size, const void *value);
- virtual void bind(exec_context &ctx);
+ virtual void bind(exec_context &ctx,
+ const clover::module::argument &marg);
virtual void unbind(exec_context &ctx);
private:
+ size_t size;
std::vector<uint8_t> v;
};
class global_argument : public argument {
public:
- global_argument(size_t size);
-
virtual void set(size_t size, const void *value);
- virtual void bind(exec_context &ctx);
+ virtual void bind(exec_context &ctx,
+ const clover::module::argument &marg);
virtual void unbind(exec_context &ctx);
private:
class local_argument : public argument {
public:
- local_argument();
-
virtual size_t storage() const;
virtual void set(size_t size, const void *value);
- virtual void bind(exec_context &ctx);
+ virtual void bind(exec_context &ctx,
+ const clover::module::argument &marg);
virtual void unbind(exec_context &ctx);
private:
class constant_argument : public argument {
public:
- constant_argument();
-
virtual void set(size_t size, const void *value);
- virtual void bind(exec_context &ctx);
+ virtual void bind(exec_context &ctx,
+ const clover::module::argument &marg);
virtual void unbind(exec_context &ctx);
private:
class image_rd_argument : public argument {
public:
- image_rd_argument();
-
virtual void set(size_t size, const void *value);
- virtual void bind(exec_context &ctx);
+ virtual void bind(exec_context &ctx,
+ const clover::module::argument &marg);
virtual void unbind(exec_context &ctx);
private:
class image_wr_argument : public argument {
public:
- image_wr_argument();
-
virtual void set(size_t size, const void *value);
- virtual void bind(exec_context &ctx);
+ virtual void bind(exec_context &ctx,
+ const clover::module::argument &marg);
virtual void unbind(exec_context &ctx);
private:
class sampler_argument : public argument {
public:
- sampler_argument();
-
virtual void set(size_t size, const void *value);
- virtual void bind(exec_context &ctx);
+ virtual void bind(exec_context &ctx,
+ const clover::module::argument &marg);
virtual void unbind(exec_context &ctx);
private: