--- src/gallium/state_trackers/clover/api/kernel.cpp | 47 ++++++++++++++++-- src/gallium/state_trackers/clover/core/kernel.cpp | 6 +++ src/gallium/state_trackers/clover/core/kernel.hpp | 1 + src/gallium/state_trackers/clover/core/module.hpp | 19 +++++-- .../state_trackers/clover/llvm/codegen/common.cpp | 58 +++++++++++++++++++++- .../state_trackers/clover/llvm/metadata.hpp | 16 ++++++ .../state_trackers/clover/tgsi/compiler.cpp | 2 +- 7 files changed, 141 insertions(+), 8 deletions(-)
diff --git a/src/gallium/state_trackers/clover/api/kernel.cpp b/src/gallium/state_trackers/clover/api/kernel.cpp index 73ba34a..13cfc08 100644 --- a/src/gallium/state_trackers/clover/api/kernel.cpp +++ b/src/gallium/state_trackers/clover/api/kernel.cpp @@ -192,9 +192,50 @@ clGetKernelWorkGroupInfo(cl_kernel d_kern, cl_device_id d_dev, CLOVER_API cl_int clGetKernelArgInfo(cl_kernel d_kern, cl_uint idx, cl_kernel_arg_info param, - size_t size, void *r_buf, size_t *r_size) { - CLOVER_NOT_SUPPORTED_UNTIL("1.2"); - return CL_KERNEL_ARG_INFO_NOT_AVAILABLE; + size_t size, void *r_buf, size_t *r_size) try { + property_buffer buf { r_buf, size, r_size }; + const auto &kern = obj(d_kern); + const auto args_info = kern.args_info(); + + if (args_info.size() == 0) + throw error(CL_KERNEL_ARG_INFO_NOT_AVAILABLE); + + if (idx >= args_info.size()) + throw error(CL_INVALID_ARG_INDEX); + + const auto &info = args_info[idx]; + + switch (param) { + case CL_KERNEL_ARG_ADDRESS_QUALIFIER: + buf.as_scalar<cl_kernel_arg_address_qualifier>() = + info.address_qualifier; + break; + + case CL_KERNEL_ARG_ACCESS_QUALIFIER: + buf.as_scalar<cl_kernel_arg_access_qualifier>() = + info.access_qualifier; + break; + + case CL_KERNEL_ARG_TYPE_NAME: + buf.as_string() = info.type_name; + break; + + case CL_KERNEL_ARG_TYPE_QUALIFIER: + buf.as_scalar<cl_kernel_arg_type_qualifier>() = info.type_qualifier; + break; + + case CL_KERNEL_ARG_NAME: + buf.as_string() = info.arg_name; + break; + + default: + throw error(CL_INVALID_VALUE); + } + + return CL_SUCCESS; + +} catch (error &e) { + return e.get(); } namespace { diff --git a/src/gallium/state_trackers/clover/core/kernel.cpp b/src/gallium/state_trackers/clover/core/kernel.cpp index 962f555..18dcd5c 100644 --- a/src/gallium/state_trackers/clover/core/kernel.cpp +++ b/src/gallium/state_trackers/clover/core/kernel.cpp @@ -140,6 +140,12 @@ kernel::args() const { return map(derefs(), _args); } +std::vector<clover::module::argument_info> +kernel::args_info() const { + const auto &syms = program().symbols(); + return find(name_equals(_name), syms).args_info; +} + const module & kernel::module(const command_queue &q) const { return program().build(q.device()).binary; diff --git a/src/gallium/state_trackers/clover/core/kernel.hpp b/src/gallium/state_trackers/clover/core/kernel.hpp index 4ba6ff4..aae51bc 100644 --- a/src/gallium/state_trackers/clover/core/kernel.hpp +++ b/src/gallium/state_trackers/clover/core/kernel.hpp @@ -134,6 +134,7 @@ namespace clover { argument_range args(); const_argument_range args() const; + std::vector<clover::module::argument_info> args_info() const; const intrusive_ref<clover::program> program; diff --git a/src/gallium/state_trackers/clover/core/module.hpp b/src/gallium/state_trackers/clover/core/module.hpp index 5db0548..5ce9492 100644 --- a/src/gallium/state_trackers/clover/core/module.hpp +++ b/src/gallium/state_trackers/clover/core/module.hpp @@ -102,16 +102,29 @@ namespace clover { semantic semantic; }; + struct argument_info { + argument_info() { } + + uint32_t address_qualifier; + uint32_t access_qualifier; + std::string type_name; + uint32_t type_qualifier; + std::string arg_name; + }; + struct symbol { symbol(const std::string &name, resource_id section, - size_t offset, const std::vector<argument> &args) : - name(name), section(section), offset(offset), args(args) { } - symbol() : name(), section(0), offset(0), args() { } + size_t offset, const std::vector<argument> &args, + const std::vector<argument_info> &args_info) : + name(name), section(section), offset(offset), + args(args), args_info(args_info) { } + symbol() : name(), section(0), offset(0), args(), args_info() { } std::string name; resource_id section; size_t offset; std::vector<argument> args; + std::vector<argument_info> args_info; }; void serialize(std::ostream &os) const; diff --git a/src/gallium/state_trackers/clover/llvm/codegen/common.cpp b/src/gallium/state_trackers/clover/llvm/codegen/common.cpp index 834b06a..07f45f9 100644 --- a/src/gallium/state_trackers/clover/llvm/codegen/common.cpp +++ b/src/gallium/state_trackers/clover/llvm/codegen/common.cpp @@ -66,6 +66,60 @@ namespace { unreachable("Unknown image type"); } + std::vector<module::argument_info> + make_args_infos(const Module &mod, const std::string &kernel_name, + const bool has_args_infos) { + if (!has_args_infos) + return {}; + + const Function &f = *mod.getFunction(kernel_name); + + std::vector<module::argument_info> infos; + for (const auto &arg : f.args()) { + module::argument_info info; + + const auto addr_space = get_uint_argument_metadata(f, arg, + "kernel_arg_addr_space"); + if (addr_space == 0) + info.address_qualifier = CL_KERNEL_ARG_ADDRESS_PRIVATE; + else if (addr_space == 1) + info.address_qualifier = CL_KERNEL_ARG_ADDRESS_GLOBAL; + else if (addr_space == 2) + info.address_qualifier = CL_KERNEL_ARG_ADDRESS_CONSTANT; + else if (addr_space == 3) + info.address_qualifier = CL_KERNEL_ARG_ADDRESS_LOCAL; + + const auto access_qual = get_argument_metadata(f, arg, + "kernel_arg_access_qual"); + if (access_qual == "read_only") + info.access_qualifier = CL_KERNEL_ARG_ACCESS_READ_ONLY; + else if (access_qual == "write_only") + info.access_qualifier = CL_KERNEL_ARG_ACCESS_WRITE_ONLY; + else if (access_qual == "read_write") + info.access_qualifier = CL_KERNEL_ARG_ACCESS_READ_WRITE; + else if (access_qual == "none") + info.access_qualifier = CL_KERNEL_ARG_ACCESS_NONE; + + info.type_name = get_argument_metadata(f, arg, "kernel_arg_type"); + + const auto type_qual = get_argument_metadata(f, arg, + "kernel_arg_type_qual"); + info.type_qualifier = CL_KERNEL_ARG_TYPE_NONE; + if (type_qual.find("const") != std::string::npos) + info.type_qualifier |= CL_KERNEL_ARG_TYPE_CONST; + if (type_qual.find("restrict") != std::string::npos) + info.type_qualifier |= CL_KERNEL_ARG_TYPE_RESTRICT; + if (type_qual.find("volatile") != std::string::npos) + info.type_qualifier |= CL_KERNEL_ARG_TYPE_VOLATILE; + + info.arg_name = get_argument_metadata(f, arg, "kernel_arg_name"); + + infos.emplace_back(info); + } + + return infos; + } + std::vector<module::argument> make_kernel_args(const Module &mod, const std::string &kernel_name, const clang::CompilerInstance &c) { @@ -196,12 +250,14 @@ clover::llvm::build_module_common(const Module &mod, unsigned> &offsets, const clang::CompilerInstance &c) { module m; + const bool has_args_infos = c.getCodeGenOpts().EmitOpenCLArgMetadata; for (const auto &name : map(std::mem_fn(&Function::getName), get_kernels(mod))) { if (offsets.count(name)) m.syms.emplace_back(name, 0, offsets.at(name), - make_kernel_args(mod, name, c)); + make_kernel_args(mod, name, c), + make_args_infos(mod, name, has_args_infos)); } m.secs.push_back(make_text_section(code)); diff --git a/src/gallium/state_trackers/clover/llvm/metadata.hpp b/src/gallium/state_trackers/clover/llvm/metadata.hpp index 814c830..ddc5259 100644 --- a/src/gallium/state_trackers/clover/llvm/metadata.hpp +++ b/src/gallium/state_trackers/clover/llvm/metadata.hpp @@ -32,6 +32,7 @@ #include "util/algorithm.hpp" #include <vector> +#include <llvm/IR/Constants.h> #include <llvm/IR/Module.h> #include <llvm/IR/Metadata.h> @@ -112,6 +113,21 @@ namespace clover { } /// + /// Extract the uint metadata node \p name corresponding to the kernel + /// argument given by \p arg. + /// + inline uint64_t + get_uint_argument_metadata(const ::llvm::Function &f, + const ::llvm::Argument &arg, + const std::string &name) { + return ::llvm::cast<::llvm::ConstantInt>( + ::llvm::dyn_cast<::llvm::ConstantAsMetadata>( + detail::get_kernel_metadata_operands(f, name)[arg.getArgNo()]) + ->getValue()) + ->getLimitedValue(UINT_MAX); + } + + /// /// Return a vector with all CL kernel functions found in the LLVM /// module \p mod. /// diff --git a/src/gallium/state_trackers/clover/tgsi/compiler.cpp b/src/gallium/state_trackers/clover/tgsi/compiler.cpp index 9bbd454..f94d19f 100644 --- a/src/gallium/state_trackers/clover/tgsi/compiler.cpp +++ b/src/gallium/state_trackers/clover/tgsi/compiler.cpp @@ -76,7 +76,7 @@ namespace { } } - m.syms.push_back({ name, 0, offset, args }); + m.syms.push_back({ name, 0, offset, args, {} }); } } -- 2.5.5 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev