mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-04 00:30:11 +01:00
clover: Add initial implementation of clCompileProgram for CL 1.2.
[ Francisco Jerez: General clean-up. ] Reviewed-by: Francisco Jerez <currojerez@riseup.net>
This commit is contained in:
parent
fead2b0463
commit
611d66fe45
7 changed files with 77 additions and 16 deletions
|
|
@ -122,7 +122,7 @@ namespace clover {
|
|||
clReleaseDevice,
|
||||
clCreateImage,
|
||||
clCreateProgramWithBuiltInKernels,
|
||||
NULL, // clCompileProgram
|
||||
clCompileProgram,
|
||||
NULL, // clLinkProgram
|
||||
clUnloadPlatformCompiler,
|
||||
NULL, // clGetKernelArgInfo
|
||||
|
|
|
|||
|
|
@ -152,14 +152,30 @@ 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 ret = clCompileProgram(d_prog, num_devs, d_devs, p_opts,
|
||||
0, NULL, NULL, pfn_notify, user_data);
|
||||
|
||||
return (ret == CL_COMPILE_PROGRAM_FAILURE ?
|
||||
CL_BUILD_PROGRAM_FAILURE : ret);
|
||||
}
|
||||
|
||||
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 : "");
|
||||
header_map headers;
|
||||
|
||||
if (bool(num_devs) != bool(d_devs) ||
|
||||
(!pfn_notify && user_data))
|
||||
(!pfn_notify && user_data) ||
|
||||
bool(num_headers) != bool(header_names))
|
||||
throw error(CL_INVALID_VALUE);
|
||||
|
||||
if (any_of([&](const device &dev) {
|
||||
|
|
@ -167,10 +183,23 @@ clBuildProgram(cl_program d_prog, cl_uint num_devs,
|
|||
}, devs))
|
||||
throw error(CL_INVALID_DEVICE);
|
||||
|
||||
if (prog.kernel_ref_count())
|
||||
if (prog.kernel_ref_count() ||
|
||||
!prog.has_source)
|
||||
throw error(CL_INVALID_OPERATION);
|
||||
|
||||
prog.build(devs, opts);
|
||||
|
||||
for_each([&](const char *name, const program &header) {
|
||||
if (!header.has_source)
|
||||
throw error(CL_INVALID_OPERATION);
|
||||
|
||||
if (!any_of(key_equals(name), headers))
|
||||
headers.push_back(compat::pair<compat::string, compat::string>(
|
||||
name, header.source()));
|
||||
},
|
||||
range(header_names, num_headers),
|
||||
objs(d_header_progs, num_headers));
|
||||
|
||||
prog.build(devs, opts, headers);
|
||||
return CL_SUCCESS;
|
||||
|
||||
} catch (error &e) {
|
||||
|
|
|
|||
|
|
@ -29,7 +29,11 @@
|
|||
#include "pipe/p_defines.h"
|
||||
|
||||
namespace clover {
|
||||
typedef compat::vector<compat::pair<compat::string,
|
||||
compat::string> > header_map;
|
||||
|
||||
module compile_program_llvm(const compat::string &source,
|
||||
const header_map &headers,
|
||||
pipe_shader_ir ir,
|
||||
const compat::string &target,
|
||||
const compat::string &opts,
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@
|
|||
//
|
||||
|
||||
#include "core/program.hpp"
|
||||
#include "core/compiler.hpp"
|
||||
|
||||
using namespace clover;
|
||||
|
||||
|
|
@ -41,7 +40,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 header_map &headers) {
|
||||
if (has_source) {
|
||||
_devices = devs;
|
||||
|
||||
|
|
@ -57,7 +57,8 @@ program::build(const ref_vector<device> &devs, const char *opts) {
|
|||
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, headers,
|
||||
dev.ir_format(),
|
||||
dev.ir_target(), build_opts(dev),
|
||||
log));
|
||||
_binaries.insert({ &dev, module });
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
#include "core/object.hpp"
|
||||
#include "core/context.hpp"
|
||||
#include "core/module.hpp"
|
||||
#include "core/compiler.hpp"
|
||||
|
||||
namespace clover {
|
||||
class program : public ref_counter, public _cl_program {
|
||||
|
|
@ -46,7 +47,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 header_map &headers);
|
||||
|
||||
const bool has_source;
|
||||
const std::string &source() const;
|
||||
|
|
|
|||
|
|
@ -146,10 +146,11 @@ namespace {
|
|||
|
||||
llvm::Module *
|
||||
compile_llvm(llvm::LLVMContext &llvm_ctx, const std::string &source,
|
||||
const std::string &name, const std::string &triple,
|
||||
const std::string &processor, const std::string &opts,
|
||||
clang::LangAS::Map& address_spaces, unsigned &optimization_level,
|
||||
compat::string &r_log) {
|
||||
const header_map &headers,
|
||||
const std::string &name, const std::string &triple,
|
||||
const std::string &processor, const std::string &opts,
|
||||
clang::LangAS::Map& address_spaces, unsigned &optimization_level,
|
||||
compat::string &r_log) {
|
||||
|
||||
clang::CompilerInstance c;
|
||||
clang::EmitLLVMOnlyAction act(&llvm_ctx);
|
||||
|
|
@ -248,6 +249,29 @@ namespace {
|
|||
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 (header_map::const_iterator it = headers.begin();
|
||||
it != headers.end(); ++it) {
|
||||
const std::string path = tmp_header_path + std::string(it->first);
|
||||
c.getPreprocessorOpts().addRemappedFile(path,
|
||||
#if HAVE_LLVM >= 0x0306
|
||||
llvm::MemoryBuffer::getMemBuffer(it->second.c_str()).release());
|
||||
#else
|
||||
llvm::MemoryBuffer::getMemBuffer(it->second.c_str()));
|
||||
#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
|
||||
|
|
@ -684,6 +708,7 @@ static const struct debug_named_value debug_options[] = {
|
|||
|
||||
module
|
||||
clover::compile_program_llvm(const compat::string &source,
|
||||
const header_map &headers,
|
||||
enum pipe_shader_ir ir,
|
||||
const compat::string &target,
|
||||
const compat::string &opts,
|
||||
|
|
@ -708,8 +733,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(llvm_ctx, source, "input.cl", triple,
|
||||
processor, opts, address_spaces,
|
||||
llvm::Module *mod = compile_llvm(llvm_ctx, source, headers, "input.cl",
|
||||
triple, processor, opts, address_spaces,
|
||||
optimization_level, r_log);
|
||||
|
||||
find_kernels(mod, kernels);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue