Signed-off-by: Pierre Moreau <pierre.mor...@free.fr> --- src/gallium/state_trackers/clover/api/program.cpp | 29 ++++++++++- src/gallium/state_trackers/clover/core/program.cpp | 57 ++++++++++++++++++++-- src/gallium/state_trackers/clover/core/program.hpp | 14 ++++++ 3 files changed, 95 insertions(+), 5 deletions(-)
diff --git a/src/gallium/state_trackers/clover/api/program.cpp b/src/gallium/state_trackers/clover/api/program.cpp index 5f5971078d..57b8aedb91 100644 --- a/src/gallium/state_trackers/clover/api/program.cpp +++ b/src/gallium/state_trackers/clover/api/program.cpp @@ -144,6 +144,31 @@ clCreateProgramWithBinary(cl_context d_ctx, cl_uint n, } CLOVER_API cl_program +clCreateProgramWithIL(cl_context d_ctx, + const void *il, + const size_t length, + cl_int *r_errcode) try { + auto &ctx = obj(d_ctx); + + if (!il || !length) + throw error(CL_INVALID_VALUE); + + uint32_t type = 0; + // Only SPIR-V is supported for now + if (!spirv_is_binary_spirv(reinterpret_cast<const char*>(il))) + throw error(CL_INVALID_VALUE); + type = PIPE_SHADER_IR_SPIRV; + + // initialize a program object with it. + ret_error(r_errcode, CL_SUCCESS); + return new program(ctx, il, length, type); + +} catch (error &e) { + ret_error(r_errcode, e); + return NULL; +} + +CLOVER_API cl_program clCreateProgramWithBuiltInKernels(cl_context d_ctx, cl_uint n, const cl_device_id *d_devs, const char *kernel_names, @@ -198,7 +223,7 @@ clBuildProgram(cl_program d_prog, cl_uint num_devs, validate_build_common(prog, num_devs, d_devs, pfn_notify, user_data); - if (prog.has_source) { + if (prog.has_source || prog.has_il) { prog.compile(devs, opts); prog.link(devs, opts, { prog }); } @@ -228,7 +253,7 @@ clCompileProgram(cl_program d_prog, cl_uint num_devs, if (bool(num_headers) != bool(header_names)) throw error(CL_INVALID_VALUE); - if (!prog.has_source) + if (!prog.has_source && !prog.has_il) throw error(CL_INVALID_OPERATION); for_each([&](const char *name, const program &header) { diff --git a/src/gallium/state_trackers/clover/core/program.cpp b/src/gallium/state_trackers/clover/core/program.cpp index 6a54500247..d9d197fffe 100644 --- a/src/gallium/state_trackers/clover/core/program.cpp +++ b/src/gallium/state_trackers/clover/core/program.cpp @@ -23,24 +23,43 @@ #include "core/program.hpp" #include "llvm/invocation.hpp" #include "tgsi/invocation.hpp" +#include "spirv/invocation.hpp" + +#include "spirv/spirv_utils.h" + +#include <cstring> using namespace clover; program::program(clover::context &ctx, const std::string &source) : - has_source(true), context(ctx), _source(source), _kernel_ref_counter(0) { + has_source(true), has_il(false), il_type(0u), context(ctx), _source(source), + _kernel_ref_counter(0), _il(nullptr), _length(0) { } program::program(clover::context &ctx, const ref_vector<device> &devs, const std::vector<module> &binaries) : - has_source(false), context(ctx), - _devices(devs), _kernel_ref_counter(0) { + has_source(false), has_il(false), il_type(0u), context(ctx), + _devices(devs), _kernel_ref_counter(0), _il(nullptr), _length(0) { for_each([&](device &dev, const module &bin) { _builds[&dev] = { bin }; }, devs, binaries); } +program::program(clover::context &ctx, const void *il, const size_t length, + const uint32_t type) : + has_source(false), has_il(true), il_type(type), context(ctx), + _kernel_ref_counter(0), _il(nullptr), _length(length) { + const char *c_il = reinterpret_cast<const char *>(il); + _il = spirv_spirv_to_cpu(c_il, length); +} + +program::~program() { + if (has_il) + delete[] reinterpret_cast<const char *>(_il); +} + void program::compile(const ref_vector<device> &devs, const std::string &opts, const header_map &headers) { @@ -65,6 +84,28 @@ program::compile(const ref_vector<device> &devs, const std::string &opts, throw; } } + } else if (has_il) { + _devices = devs; + + for (auto &dev : devs) { + std::string log; + + try { + if (il_type == PIPE_SHADER_IR_SPIRV) { + if (!dev.supports_ir(PIPE_SHADER_IR_SPIRV)) { + log = "Device does not support SPIR-V as IL\n"; + throw error(CL_INVALID_BINARY); + } + _builds[&dev] = { spirv::process_program(_il, _length, false, log), opts, log }; + } else { + log = "Only SPIR-V is supported as IL by clover for now\n"; + throw error(CL_INVALID_BINARY); + } + } catch (const error &) { + _builds[&dev] = { module(), opts, log }; + throw; + } + } } } @@ -101,6 +142,16 @@ program::link(const ref_vector<device> &devs, const std::string &opts, } } +const void * +program::il() const { + return _il; +} + +size_t +program::length() const { + return _length; +} + const std::string & program::source() const { return _source; diff --git a/src/gallium/state_trackers/clover/core/program.hpp b/src/gallium/state_trackers/clover/core/program.hpp index 05964e78a7..77a79c5d94 100644 --- a/src/gallium/state_trackers/clover/core/program.hpp +++ b/src/gallium/state_trackers/clover/core/program.hpp @@ -43,11 +43,17 @@ namespace clover { program(clover::context &ctx, const ref_vector<device> &devs = {}, const std::vector<module> &binaries = {}); + program(clover::context &ctx, + const void *il, + const size_t length, + const uint32_t type); program(const program &prog) = delete; program & operator=(const program &prog) = delete; + ~program(); + void compile(const ref_vector<device> &devs, const std::string &opts, const header_map &headers = {}); void link(const ref_vector<device> &devs, const std::string &opts, @@ -56,6 +62,12 @@ namespace clover { const bool has_source; const std::string &source() const; + const bool has_il; + const uint32_t il_type; + const void *il() const; + + size_t length() const; + device_range devices() const; struct build { @@ -85,6 +97,8 @@ namespace clover { std::map<const device *, struct build> _builds; std::string _source; ref_counter _kernel_ref_counter; + const void *_il; + size_t _length; }; } -- 2.12.2 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev