[Mesa-dev] [PATCH 3/3] clover: add clCompile
EdB
edb+mesa at sigluy.net
Sun Sep 28 03:57:22 PDT 2014
---
src/gallium/state_trackers/clover/api/dispatch.cpp | 2 +-
src/gallium/state_trackers/clover/api/program.cpp | 39 +++++++++++++++++++---
.../state_trackers/clover/core/compiler.hpp | 12 ++++---
src/gallium/state_trackers/clover/core/error.hpp | 2 +-
src/gallium/state_trackers/clover/core/program.cpp | 14 ++++++--
src/gallium/state_trackers/clover/core/program.hpp | 5 ++-
.../state_trackers/clover/llvm/invocation.cpp | 39 ++++++++++++++++++----
7 files changed, 93 insertions(+), 20 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 6771735..33df0cd 100644
--- a/src/gallium/state_trackers/clover/api/program.cpp
+++ b/src/gallium/state_trackers/clover/api/program.cpp
@@ -152,14 +152,34 @@ CLOVER_API cl_int
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 {
+ void *user_data) {
+ cl_int error = clCompileProgram(d_prog, num_devs, d_devs, p_opts,
+ 0, 0, 0,
+ pfn_notify, user_data);
+ return error == CL_COMPILE_PROGRAM_FAILURE ?
+ CL_BUILD_PROGRAM_FAILURE : error;
+}
+
+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) {
@@ -170,7 +190,18 @@ clBuildProgram(cl_program d_prog, cl_uint num_devs,
if (prog.kernel_ref_count())
throw error(CL_INVALID_OPERATION);
- prog.build(devs, opts);
+ std::map<const std::string, const std::string> headers;
+ for (cl_uint i = 0; i < num_headers; ++i) {
+ auto h_name = std::string(header_names[i]);
+ auto &h_prog = obj(d_header_progs[i]);
+
+ 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..c2c4063 100644
--- a/src/gallium/state_trackers/clover/core/compiler.hpp
+++ b/src/gallium/state_trackers/clover/core/compiler.hpp
@@ -29,11 +29,15 @@
#include "pipe/p_defines.h"
namespace clover {
+ typedef compat::pair<compat::vector_ref<const char>,
+ compat::vector_ref<const char> > vector_ref_pair;
+
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<vector_ref_pair> &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/error.hpp b/src/gallium/state_trackers/clover/core/error.hpp
index cecbe9b..7b010f1 100644
--- a/src/gallium/state_trackers/clover/core/error.hpp
+++ b/src/gallium/state_trackers/clover/core/error.hpp
@@ -67,7 +67,7 @@ namespace clover {
class build_error : public error {
public:
build_error(const compat::string &what = "") :
- error(CL_BUILD_PROGRAM_FAILURE, what) {
+ error(CL_COMPILE_PROGRAM_FAILURE, what) {
}
};
diff --git a/src/gallium/state_trackers/clover/core/program.cpp b/src/gallium/state_trackers/clover/core/program.cpp
index 6c224db..0940697 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<vector_ref_pair> cpt_headers;
+ for (auto &header : headers) {
+ vector_ref_pair h;
+ h.first = header.first;
+ h.second = header.second;
+ cpt_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, cpt_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 4bb5b68..8e05075 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 7bca0d6..9f16adc 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<vector_ref_pair> &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) {
@@ -213,12 +214,35 @@ namespace {
#if HAVE_LLVM >= 0x0306
c.getPreprocessorOpts().addRemappedFile(name,
- llvm::MemoryBuffer::getMemBuffer(source).release());
+ llvm::MemoryBuffer::getMemBuffer(source).release());
#else
c.getPreprocessorOpts().addRemappedFile(name,
llvm::MemoryBuffer::getMemBuffer(source));
#endif
+ if (headers.size()) {
+ 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 (size_t i = 0; i < headers.size(); ++i) {
+ vector_ref_pair header = headers[i];
+ const std::string path = tmp_header_path + std::string(header.first.begin());
+ c.getPreprocessorOpts().addRemappedFile(path,
+#if HAVE_LLVM >= 0x0306
+ llvm::MemoryBuffer::getMemBuffer(header.second.begin()).release());
+#else
+ llvm::MemoryBuffer::getMemBuffer(header.second.begin()));
+#endif
+ }
+ }
+
// 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
@@ -401,10 +425,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<vector_ref_pair> &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("-");
@@ -417,8 +442,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.1.1
More information about the mesa-dev
mailing list