--- src/gallium/state_trackers/clover/api/kernel.cpp | 92 +++++++++++++++++++++- src/gallium/state_trackers/clover/core/module.cpp | 14 ++++ src/gallium/state_trackers/clover/core/module.hpp | 11 +++ .../state_trackers/clover/llvm/codegen/common.cpp | 11 +++ 4 files changed, 125 insertions(+), 3 deletions(-)
diff --git a/src/gallium/state_trackers/clover/api/kernel.cpp b/src/gallium/state_trackers/clover/api/kernel.cpp index 73ba34a..81a4a38 100644 --- a/src/gallium/state_trackers/clover/api/kernel.cpp +++ b/src/gallium/state_trackers/clover/api/kernel.cpp @@ -192,9 +192,95 @@ 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 = + find(name_equals(kern.name()), kern.program().symbols()).args; + + if (args.at(0).arg_info.arg_name.empty()) + throw error(CL_KERNEL_ARG_INFO_NOT_AVAILABLE); + + const auto &arg = find([&](const clover::module::argument &arg) { + return arg.arg_info.index == idx; + }, args); + + switch (param) { + case CL_KERNEL_ARG_ADDRESS_QUALIFIER: { + cl_kernel_arg_address_qualifier v; + switch (arg.type) { + case module::argument::local: + v = CL_KERNEL_ARG_ADDRESS_LOCAL; + break; + case module::argument::constant: + v = CL_KERNEL_ARG_ADDRESS_CONSTANT; + break; + case module::argument::global: + case module::argument::image2d_rd: + case module::argument::image2d_wr: + case module::argument::image3d_rd: + case module::argument::image3d_wr: + v = CL_KERNEL_ARG_ADDRESS_GLOBAL; + break; + default: + v = CL_KERNEL_ARG_ADDRESS_PRIVATE; + } + buf.as_scalar<cl_kernel_arg_address_qualifier>() = v; + break; + } + + case CL_KERNEL_ARG_ACCESS_QUALIFIER: { + cl_kernel_arg_access_qualifier v; + switch (arg.type) { + case module::argument::image2d_rd: + case module::argument::image3d_rd: + v = CL_KERNEL_ARG_ACCESS_READ_ONLY; + break; + case module::argument::image2d_wr: + case module::argument::image3d_wr: + v = CL_KERNEL_ARG_ACCESS_WRITE_ONLY; + break; + default: + v = CL_KERNEL_ARG_ACCESS_NONE; + } + buf.as_scalar<cl_kernel_arg_access_qualifier>() = v; + break; + } + + case CL_KERNEL_ARG_TYPE_NAME: + buf.as_string() = arg.arg_info.type_name; + break; + + case CL_KERNEL_ARG_TYPE_QUALIFIER: { + cl_kernel_arg_type_qualifier v = CL_KERNEL_ARG_TYPE_NONE; + + if (arg.arg_info.type_qualifier.find("const") != std::string::npos) + v |= CL_KERNEL_ARG_TYPE_CONST; + if (arg.arg_info.type_qualifier.find("restrict") != std::string::npos) + v |= CL_KERNEL_ARG_TYPE_RESTRICT; + if (arg.arg_info.type_qualifier.find("volatile") != std::string::npos) + v |= CL_KERNEL_ARG_TYPE_VOLATILE; + + buf.as_scalar<cl_kernel_arg_type_qualifier>() = v; + break; + } + + case CL_KERNEL_ARG_NAME: + buf.as_string() = arg.arg_info.arg_name; + break; + + default: + throw error(CL_INVALID_VALUE); + } + + return CL_SUCCESS; + +} catch (std::out_of_range &e) { + return CL_INVALID_ARG_INDEX; + +} catch (error &e) { + return e.get(); } namespace { diff --git a/src/gallium/state_trackers/clover/core/module.cpp b/src/gallium/state_trackers/clover/core/module.cpp index a6c5b98..1b6b642 100644 --- a/src/gallium/state_trackers/clover/core/module.cpp +++ b/src/gallium/state_trackers/clover/core/module.cpp @@ -168,6 +168,19 @@ namespace { } }; + /// (De)serialize a module::argument::info + template<> + struct _serializer<module::argument::info> { + template<typename S, typename QT> + static void + proc(S &s, QT &x) { + _proc(s, x.index); + _proc(s, x.type_name); + _proc(s, x.type_qualifier); + _proc(s, x.arg_name); + } + }; + /// (De)serialize a module::argument. template<> struct _serializer<module::argument> { @@ -180,6 +193,7 @@ namespace { _proc(s, x.target_align); _proc(s, x.ext_type); _proc(s, x.semantic); + _proc(s, x.arg_info); } }; diff --git a/src/gallium/state_trackers/clover/core/module.hpp b/src/gallium/state_trackers/clover/core/module.hpp index 2ddd264..4425df9 100644 --- a/src/gallium/state_trackers/clover/core/module.hpp +++ b/src/gallium/state_trackers/clover/core/module.hpp @@ -54,6 +54,16 @@ namespace clover { }; struct argument { + struct info { + info() : + index(-1), type_name(""), type_qualifier(""), arg_name("") { } + + size_t index; + std::string type_name; + std::string type_qualifier; + std::string arg_name; + }; + enum type { scalar, constant, @@ -102,6 +112,7 @@ namespace clover { size_t target_align; ext_type ext_type; semantic semantic; + info arg_info; }; struct symbol { diff --git a/src/gallium/state_trackers/clover/llvm/codegen/common.cpp b/src/gallium/state_trackers/clover/llvm/codegen/common.cpp index aa6ca50..03b9a88 100644 --- a/src/gallium/state_trackers/clover/llvm/codegen/common.cpp +++ b/src/gallium/state_trackers/clover/llvm/codegen/common.cpp @@ -69,6 +69,7 @@ namespace { std::vector<module::argument> make_kernel_args(const Module &mod, const std::string &kernel_name, const clang::CompilerInstance &c) { + const bool get_args_infos = c.getCodeGenOpts().EmitOpenCLArgMetadata; std::vector<module::argument> args; const auto address_spaces = c.getTarget().getAddressSpaceMap(); const Function &f = *mod.getFunction(kernel_name); @@ -161,6 +162,16 @@ namespace { module::argument::zero_ext)); } } + + if (get_args_infos) { + struct module::argument::info i; + i.index = arg.getArgNo(); + i.type_name = get_argument_metadata(f, arg, "kernel_arg_type"); + i.type_qualifier = get_argument_metadata(f, arg, "kernel_arg_type_qual"); + i.arg_name = get_argument_metadata(f, arg, "kernel_arg_name"); + args.back().arg_info = i; + } + } // Append implicit arguments. XXX - The types, ordering and -- 2.5.5 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev