--- src/gallium/state_trackers/clover/api/dispatch.cpp | 2 +- src/gallium/state_trackers/clover/api/program.cpp | 41 ++++++++++++++++++++-- .../state_trackers/clover/core/compiler.hpp | 11 +++--- src/gallium/state_trackers/clover/core/program.cpp | 14 ++++++-- src/gallium/state_trackers/clover/core/program.hpp | 5 ++- .../state_trackers/clover/llvm/invocation.cpp | 33 +++++++++++++---- 6 files changed, 89 insertions(+), 17 deletions(-)
diff --git a/src/gallium/state_trackers/clover/api/dispatch.cpp b/src/gallium/state_trackers/clover/api/dispatch.cpp index 35d150d..b5a4094 100644 --- a/src/gallium/state_trackers/clover/api/dispatch.cpp +++ b/src/gallium/state_trackers/clover/api/dispatch.cpp @@ -122,7 +122,7 @@ namespace clover { clReleaseDevice, clCreateImage, clCreateProgramWithBuiltInKernels, - NULL, // clCompileProgram + clCompileProgram, NULL, // clLinkProgram clUnloadPlatformCompiler, NULL, // clGetKernelArgInfo diff --git a/src/gallium/state_trackers/clover/api/program.cpp b/src/gallium/state_trackers/clover/api/program.cpp index b81ce69..b0a906e 100644 --- a/src/gallium/state_trackers/clover/api/program.cpp +++ b/src/gallium/state_trackers/clover/api/program.cpp @@ -153,13 +153,35 @@ clBuildProgram(cl_program d_prog, cl_uint num_devs, const cl_device_id *d_devs, const char *p_opts, void (*pfn_notify)(cl_program, void *), void *user_data) try { + return clCompileProgram(d_prog, num_devs, d_devs, p_opts, + 0, 0, 0, + pfn_notify, user_data); + +} catch (error &e) { + return e.get(); +} + +CLOVER_API cl_int +clCompileProgram(cl_program d_prog, cl_uint num_devs, + const cl_device_id *d_devs, const char *p_opts, + cl_uint num_headers, const cl_program *d_header_progs, + const char **header_names, + void (*pfn_notify)(cl_program, void *), + void *user_data) try { + auto &prog = obj(d_prog); auto devs = (d_devs ? objs(d_devs, num_devs) : ref_vector<device>(prog.context().devices())); auto opts = (p_opts ? p_opts : ""); - if (bool(num_devs) != bool(d_devs) || - (!pfn_notify && user_data)) + if (bool(num_devs) != bool(d_devs)) + throw error(CL_INVALID_VALUE); + + if (!pfn_notify && user_data) + throw error(CL_INVALID_VALUE); + + if (bool(num_headers) != bool(header_names) || + bool(num_headers) != bool(d_header_progs)) throw error(CL_INVALID_VALUE); if (any_of([&](const device &dev) { @@ -167,7 +189,20 @@ clBuildProgram(cl_program d_prog, cl_uint num_devs, }, devs)) throw error(CL_INVALID_DEVICE); - prog.build(devs, opts); + std::map<const std::string, const std::string> headers; + for (unsigned int i = 0; i < num_headers; ++i) { + auto h_name = std::string(header_names[i]); + auto &h_prog = obj(d_header_progs[i]); + + // The specs is unclear on what to do in that case, + // however it says that headers have to be with sources + if (!h_prog.has_source) + throw error(CL_INVALID_OPERATION); + + headers.insert(make_pair(h_name, h_prog.source())); + } + + prog.build(devs, opts, headers); return CL_SUCCESS; } catch (error &e) { diff --git a/src/gallium/state_trackers/clover/core/compiler.hpp b/src/gallium/state_trackers/clover/core/compiler.hpp index 6ef84d1..3b1d9fc 100644 --- a/src/gallium/state_trackers/clover/core/compiler.hpp +++ b/src/gallium/state_trackers/clover/core/compiler.hpp @@ -23,6 +23,8 @@ #ifndef CLOVER_CORE_COMPILER_HPP #define CLOVER_CORE_COMPILER_HPP +#include <map> + #include "util/compat.hpp" #include "core/error.hpp" #include "core/module.hpp" @@ -30,10 +32,11 @@ namespace clover { module compile_program_llvm(const compat::string &source, - pipe_shader_ir ir, - const compat::string &target, - const compat::string &opts, - compat::string &r_log); + const compat::vector<compat::pair<const char*>> &headers, + pipe_shader_ir ir, + const compat::string &target, + const compat::string &opts, + compat::string &r_log); module compile_program_tgsi(const compat::string &source); } diff --git a/src/gallium/state_trackers/clover/core/program.cpp b/src/gallium/state_trackers/clover/core/program.cpp index e09c3aa..b0a0a25 100644 --- a/src/gallium/state_trackers/clover/core/program.cpp +++ b/src/gallium/state_trackers/clover/core/program.cpp @@ -41,7 +41,8 @@ program::program(clover::context &ctx, } void -program::build(const ref_vector<device> &devs, const char *opts) { +program::build(const ref_vector<device> &devs, const char *opts, + const string_map &headers) { if (has_source) { _devices = devs; @@ -54,10 +55,19 @@ program::build(const ref_vector<device> &devs, const char *opts) { compat::string log; + compat::vector<compat::pair<const char*>> compat_headers; + for (auto &header : headers) { + compat::pair<const char*> h; + h.first = header.first.c_str(); + h.second = header.second.c_str(); + compat_headers.push_back(h); + } + try { auto module = (dev.ir_format() == PIPE_SHADER_IR_TGSI ? compile_program_tgsi(_source) : - compile_program_llvm(_source, dev.ir_format(), + compile_program_llvm(_source, compat_headers, + dev.ir_format(), dev.ir_target(), build_opts(dev), log)); _binaries.insert({ &dev, module }); diff --git a/src/gallium/state_trackers/clover/core/program.hpp b/src/gallium/state_trackers/clover/core/program.hpp index 1081454..f5a4214 100644 --- a/src/gallium/state_trackers/clover/core/program.hpp +++ b/src/gallium/state_trackers/clover/core/program.hpp @@ -29,6 +29,8 @@ #include "core/context.hpp" #include "core/module.hpp" +typedef std::map<const std::string, const std::string> string_map; + namespace clover { class program : public ref_counter, public _cl_program { private: @@ -46,7 +48,8 @@ namespace clover { program & operator=(const program &prog) = delete; - void build(const ref_vector<device> &devs, const char *opts); + void build(const ref_vector<device> &devs, const char *opts, + const string_map &headers); const bool has_source; const std::string &source() const; diff --git a/src/gallium/state_trackers/clover/llvm/invocation.cpp b/src/gallium/state_trackers/clover/llvm/invocation.cpp index 5d2efc4..2db59be 100644 --- a/src/gallium/state_trackers/clover/llvm/invocation.cpp +++ b/src/gallium/state_trackers/clover/llvm/invocation.cpp @@ -118,6 +118,7 @@ namespace { llvm::Module * compile(llvm::LLVMContext &llvm_ctx, const std::string &source, + const compat::vector<compat::pair<const char*>> &headers, const std::string &name, const std::string &triple, const std::string &processor, const std::string &opts, clang::LangAS::Map& address_spaces, compat::string &r_log) { @@ -214,6 +215,25 @@ namespace { c.getPreprocessorOpts().addRemappedFile(name, llvm::MemoryBuffer::getMemBuffer(source)); + if (headers.size() > 0) { + const std::string tmp_header_path = "/tmp/clover/"; + + c.getHeaderSearchOpts().AddPath(tmp_header_path, + clang::frontend::Angled, + false, false + #if HAVE_LLVM < 0x0303 + , false + #endif + ); + + for (auto &header : headers) { + const std::string path = tmp_header_path + std::string(header.first); + c.getPreprocessorOpts().addRemappedFile(path, + llvm::MemoryBuffer::getMemBuffer(header.second)); + } + } + + // Setting this attribute tells clang to link this file before // performing any optimizations. This is required so that // we can replace calls to the OpenCL C barrier() builtin @@ -392,10 +412,11 @@ namespace { module clover::compile_program_llvm(const compat::string &source, - enum pipe_shader_ir ir, - const compat::string &target, - const compat::string &opts, - compat::string &r_log) { + const compat::vector<compat::pair<const char*>> &headers, + enum pipe_shader_ir ir, + const compat::string &target, + const compat::string &opts, + compat::string &r_log) { std::vector<llvm::Function *> kernels; size_t processor_str_len = std::string(target.begin()).find_first_of("-"); @@ -408,8 +429,8 @@ clover::compile_program_llvm(const compat::string &source, // The input file name must have the .cl extension in order for the // CompilerInvocation class to recognize it as an OpenCL source file. - llvm::Module *mod = compile(llvm_ctx, source, "input.cl", triple, processor, - opts, address_spaces, r_log); + llvm::Module *mod = compile(llvm_ctx, source, headers, "input.cl", + triple, processor, opts, address_spaces, r_log); find_kernels(mod, kernels); -- 2.0.4 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev