Signed-off-by: Pierre Moreau <pierre.mor...@free.fr> --- src/gallium/state_trackers/clover/api/dispatch.hpp | 4 ++ src/gallium/state_trackers/clover/api/program.cpp | 29 ++++++++- src/gallium/state_trackers/clover/core/program.cpp | 68 +++++++++++++++++++++- src/gallium/state_trackers/clover/core/program.hpp | 14 +++++ 4 files changed, 110 insertions(+), 5 deletions(-)
diff --git a/src/gallium/state_trackers/clover/api/dispatch.hpp b/src/gallium/state_trackers/clover/api/dispatch.hpp index 0910e19422..21bd379fe6 100644 --- a/src/gallium/state_trackers/clover/api/dispatch.hpp +++ b/src/gallium/state_trackers/clover/api/dispatch.hpp @@ -900,6 +900,10 @@ namespace clover { cl_int IcdGetPlatformIDsKHR(cl_uint num_entries, cl_platform_id *rd_platforms, cl_uint *rnum_platforms); + + cl_program + CreateProgramWithILKHR(cl_context d_ctx, const void *il, + const size_t length, cl_int *r_errcode); } #endif diff --git a/src/gallium/state_trackers/clover/api/program.cpp b/src/gallium/state_trackers/clover/api/program.cpp index 6ec87ad128..ed3b679c7c 100644 --- a/src/gallium/state_trackers/clover/api/program.cpp +++ b/src/gallium/state_trackers/clover/api/program.cpp @@ -22,6 +22,7 @@ #include "api/util.hpp" #include "core/program.hpp" +#include "spirv/invocation.hpp" #include "util/u_debug.h" #include <sstream> @@ -128,6 +129,30 @@ clCreateProgramWithBinary(cl_context d_ctx, cl_uint n, return NULL; } +cl_program +clover::CreateProgramWithILKHR(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 = UINT32_MAX; + if (spirv::is_binary_spirv(reinterpret_cast<const char*>(il))) + type = PIPE_SHADER_IR_SPIRV; + + if (type == UINT32_MAX) + throw error(CL_INVALID_VALUE); + + // 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, @@ -183,7 +208,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 }); } else if (any_of([&](const device &dev){ @@ -221,7 +246,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 976213ef95..b9ba38d4e6 100644 --- a/src/gallium/state_trackers/clover/core/program.cpp +++ b/src/gallium/state_trackers/clover/core/program.cpp @@ -24,24 +24,51 @@ #include "llvm/invocation.hpp" #include "spirv/invocation.hpp" #include "tgsi/invocation.hpp" +#include "spirv/invocation.hpp" + +#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(UINT32_MAX), 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(UINT32_MAX), 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) { + switch (il_type) { + case PIPE_SHADER_IR_SPIRV: { + const char *c_il = reinterpret_cast<const char *>(il); + _il = spirv::spirv_to_cpu(c_il, length); + } + break; + } +} + +program::~program() { + if (has_il) { + switch (il_type) { + case PIPE_SHADER_IR_SPIRV: + delete[] reinterpret_cast<const char *>(_il); + break; + } + } +} + void program::compile(const ref_vector<device> &devs, const std::string &opts, const header_map &headers) { @@ -66,6 +93,31 @@ 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 { + switch (il_type) { + case 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, dev, log), + opts, log }; + break; + default: + 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; + } + } } } @@ -104,6 +156,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.16.0 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev