From: Tom Stellard <thomas.stell...@amd.com> v2: - Use a 'pad' argument to align arguments to the correct size. --- .../state_trackers/clover/core/compiler.hpp | 3 +- src/gallium/state_trackers/clover/core/kernel.cpp | 16 ++++++- src/gallium/state_trackers/clover/core/kernel.hpp | 3 ++ src/gallium/state_trackers/clover/core/module.hpp | 13 ++++-- src/gallium/state_trackers/clover/core/program.cpp | 4 +- .../state_trackers/clover/llvm/invocation.cpp | 53 ++++++++++++++++++---- .../state_trackers/clover/tgsi/compiler.cpp | 27 +++++++---- 7 files changed, 91 insertions(+), 28 deletions(-)
diff --git a/src/gallium/state_trackers/clover/core/compiler.hpp b/src/gallium/state_trackers/clover/core/compiler.hpp index b8af1c8..b1df312 100644 --- a/src/gallium/state_trackers/clover/core/compiler.hpp +++ b/src/gallium/state_trackers/clover/core/compiler.hpp @@ -54,8 +54,7 @@ namespace clover { }; module compile_program_llvm(const compat::string &source, - enum pipe_shader_ir ir, - const compat::string &target, + const struct pipe_screen *pipe, const compat::string &opts); module compile_program_tgsi(const compat::string &source); diff --git a/src/gallium/state_trackers/clover/core/kernel.cpp b/src/gallium/state_trackers/clover/core/kernel.cpp index c95285d..2b6fbe5 100644 --- a/src/gallium/state_trackers/clover/core/kernel.cpp +++ b/src/gallium/state_trackers/clover/core/kernel.cpp @@ -31,6 +31,8 @@ _cl_kernel::_cl_kernel(clover::program &prog, const std::vector<clover::module::argument> &args) : prog(prog), __name(name), exec(*this) { for (auto arg : args) { + if (arg.type == module::argument::pad) + continue; if (arg.type == module::argument::scalar) this->args.emplace_back(new scalar_argument(arg.size)); else if (arg.type == module::argument::global) @@ -129,6 +131,10 @@ _cl_kernel::module(const clover::command_queue &q) const { return prog.binaries().find(&q.dev)->second; } +const clover::compat::vector<clover::module::argument> & +_cl_kernel::module_args(const clover::command_queue &q) const { + return module(q).sym(__name).args; +} _cl_kernel::exec_context::exec_context(clover::kernel &kern) : kern(kern), q(NULL), mem_local(0), st(NULL) { @@ -143,8 +149,14 @@ void * _cl_kernel::exec_context::bind(clover::command_queue *__q) { std::swap(q, __q); - for (auto &arg : kern.args) - arg->bind(*this); + for (const clover::module::argument &arg : kern.module_args(*q)) { + if (arg.type == clover::module::argument::pad) { + input.resize(input.size() + arg.size); + } else { + assert(arg.arg_index >= 0); + kern.args[arg.arg_index]->bind(*this); + } + } // Create a new compute state if anything changed. if (!st || q != __q || diff --git a/src/gallium/state_trackers/clover/core/kernel.hpp b/src/gallium/state_trackers/clover/core/kernel.hpp index 6b336d0..2c540be 100644 --- a/src/gallium/state_trackers/clover/core/kernel.hpp +++ b/src/gallium/state_trackers/clover/core/kernel.hpp @@ -117,6 +117,9 @@ private: const clover::module & module(const clover::command_queue &q) const; + const clover::compat::vector<clover::module::argument> & + module_args(const clover::command_queue &q) const; + class scalar_argument : public argument { public: scalar_argument(size_t size); diff --git a/src/gallium/state_trackers/clover/core/module.hpp b/src/gallium/state_trackers/clover/core/module.hpp index 88dfc9f..d4b3413 100644 --- a/src/gallium/state_trackers/clover/core/module.hpp +++ b/src/gallium/state_trackers/clover/core/module.hpp @@ -65,14 +65,21 @@ namespace clover { image2d_wr, image3d_rd, image3d_wr, - sampler + sampler, + pad }; - argument(enum type type, size_t size) : type(type), size(size) { } - argument() : type(scalar), size(0) { } + argument(enum type type, size_t size, size_t arg_index) : type(type), + size(size), arg_index(arg_index) { } + argument(enum type type, size_t size) : type(type), size(size), + arg_index(-1) { } + argument() : type(scalar), size(0), arg_index(-1) { } type type; size_t size; + /// The index of this argument in the function. If arg_index is -1, + /// then this arguement is not a formal argument of the function. + size_t arg_index; }; struct symbol { diff --git a/src/gallium/state_trackers/clover/core/program.cpp b/src/gallium/state_trackers/clover/core/program.cpp index e85f27a..1e5a126 100644 --- a/src/gallium/state_trackers/clover/core/program.cpp +++ b/src/gallium/state_trackers/clover/core/program.cpp @@ -53,8 +53,8 @@ _cl_program::build(const std::vector<clover::device *> &devs, try { auto module = (dev->ir_format() == PIPE_SHADER_IR_TGSI ? compile_program_tgsi(__source) : - compile_program_llvm(__source, dev->ir_format(), - dev->ir_target(), build_opts(dev))); + compile_program_llvm(__source, dev->get_pipe(), + build_opts(dev))); __binaries.insert({ dev, module }); } catch (build_error &e) { diff --git a/src/gallium/state_trackers/clover/llvm/invocation.cpp b/src/gallium/state_trackers/clover/llvm/invocation.cpp index dae61f7..68f7eac 100644 --- a/src/gallium/state_trackers/clover/llvm/invocation.cpp +++ b/src/gallium/state_trackers/clover/llvm/invocation.cpp @@ -20,6 +20,7 @@ // OTHER DEALINGS IN THE SOFTWARE. // +#include "pipe/p_screen.h" #include "core/compiler.hpp" #include <clang/Frontend/CompilerInstance.h> @@ -58,6 +59,7 @@ #endif #include "pipe/p_state.h" +#include "util/u_math.h" #include "util/u_memory.h" #include <iostream> @@ -282,6 +284,7 @@ namespace { module build_module_llvm(llvm::Module *mod, + const struct pipe_screen *pipe, const std::vector<llvm::Function *> &kernels) { module m; @@ -311,6 +314,18 @@ namespace { llvm::DataLayout TD(kernel_func->getParent()->getDataLayout()); #endif unsigned arg_size = TD.getTypeStoreSize(arg_type); + size_t alignment = arg_size; + pipe->get_compute_param(pipe, PIPE_COMPUTE_CAP_KERNEL_ARG_ALIGNMENT, + &alignment); + unsigned aligned_size = align(arg_size, alignment); + size_t target_size; + if (arg_type->isIntegerTy()) { + llvm::Type *target_type = TD.getSmallestLegalIntType( + mod->getContext(), arg_type->getPrimitiveSizeInBits()); + target_size = target_type->getPrimitiveSizeInBits(); + } else { + target_size = aligned_size; + } if (llvm::isa<llvm::PointerType>(arg_type) && arg.hasByValAttr()) { arg_type = @@ -324,11 +339,17 @@ namespace { unsigned address_space = llvm::cast<llvm::PointerType>(arg_type)->getAddressSpace(); switch (address_space) { default: - args.push_back(module::argument(module::argument::global, arg_size)); + args.push_back(module::argument(module::argument::global, + arg_size, arg.getArgNo())); break; } } else { - args.push_back(module::argument(module::argument::scalar, arg_size)); + args.push_back(module::argument(module::argument::scalar, + arg_size, arg.getArgNo())); + } + if (aligned_size > target_size) { + args.push_back(module::argument(module::argument::pad, + aligned_size - target_size)); } } @@ -349,15 +370,24 @@ namespace { module clover::compile_program_llvm(const compat::string &source, - enum pipe_shader_ir ir, - const compat::string &target, + const struct pipe_screen *pipe, const compat::string &opts) { std::vector<llvm::Function *> kernels; - size_t processor_str_len = std::string(target.begin()).find_first_of("-"); - std::string processor(target.begin(), 0, processor_str_len); - std::string triple(target.begin(), processor_str_len + 1, - target.size() - processor_str_len - 1); + enum pipe_shader_ir ir = (enum pipe_shader_ir) pipe->get_shader_param(pipe, + PIPE_SHADER_COMPUTE, + PIPE_SHADER_CAP_PREFERRED_IR); + size_t target_str_len = pipe->get_compute_param(pipe, + PIPE_COMPUTE_CAP_IR_TARGET, NULL); + char *target = (char*)MALLOC(target_str_len); + pipe->get_compute_param(pipe, PIPE_COMPUTE_CAP_IR_TARGET, target); + + size_t processor_str_len = strchr(target, '-') - target; + char *triple_start = target + processor_str_len + 1; + size_t triple_str_len = strlen(target) - processor_str_len - 1; + + std::string processor(target, processor_str_len); + std::string triple(triple_start, triple_str_len); // The input file name must have the .cl extension in order for the // CompilerInvocation class to recognize it as an OpenCL source file. @@ -367,13 +397,16 @@ clover::compile_program_llvm(const compat::string &source, link(mod, triple, processor, kernels); + module clover_mod; // Build the clover::module switch (ir) { case PIPE_SHADER_IR_TGSI: //XXX: Handle TGSI assert(0); - return module(); + clover_mod = module(); default: - return build_module_llvm(mod, kernels); + clover_mod = build_module_llvm(mod, pipe, kernels); } + FREE(target); + return clover_mod; } diff --git a/src/gallium/state_trackers/clover/tgsi/compiler.cpp b/src/gallium/state_trackers/clover/tgsi/compiler.cpp index 93dfeb5..698c504 100644 --- a/src/gallium/state_trackers/clover/tgsi/compiler.cpp +++ b/src/gallium/state_trackers/clover/tgsi/compiler.cpp @@ -50,23 +50,32 @@ namespace { while (ts >> tok) { if (tok == "scalar") - args.push_back({ module::argument::scalar, 4 }); + args.push_back({ module::argument::scalar, 4, + (module::size_t) args.size() }); else if (tok == "global") - args.push_back({ module::argument::global, 4 }); + args.push_back({ module::argument::global, 4, + (module::size_t) args.size() }); else if (tok == "local") - args.push_back({ module::argument::local, 4 }); + args.push_back({ module::argument::local, 4, + (module::size_t) args.size() }); else if (tok == "constant") - args.push_back({ module::argument::constant, 4 }); + args.push_back({ module::argument::constant, 4, + (module::size_t) args.size() }); else if (tok == "image2d_rd") - args.push_back({ module::argument::image2d_rd, 4 }); + args.push_back({ module::argument::image2d_rd, 4, + (module::size_t) args.size() }); else if (tok == "image2d_wr") - args.push_back({ module::argument::image2d_wr, 4 }); + args.push_back({ module::argument::image2d_wr, 4, + (module::size_t) args.size() }); else if (tok == "image3d_rd") - args.push_back({ module::argument::image3d_rd, 4 }); + args.push_back({ module::argument::image3d_rd, 4, + (module::size_t) args.size() }); else if (tok == "image3d_wr") - args.push_back({ module::argument::image3d_wr, 4 }); + args.push_back({ module::argument::image3d_wr, 4, + (module::size_t) args.size() }); else if (tok == "sampler") - args.push_back({ module::argument::sampler, 0 }); + args.push_back({ module::argument::sampler, 0, + (module::size_t) args.size() }); else throw build_error("invalid kernel argument"); } -- 1.7.11.4 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev