[Mesa-dev] [PATCH 6/7] clover: Align kernel arguments when storing them in the input buffer v2
Tom Stellard
tom at stellard.net
Tue Jul 9 21:21:43 PDT 2013
From: Tom Stellard <thomas.stellard at amd.com>
v2:
- Use a 'pad' argument to align arguments to the correct size.
---
.../state_trackers/clover/core/compiler.hpp | 3 +-
src/gallium/state_trackers/clover/core/kernel.cpp | 16 ++++++-
src/gallium/state_trackers/clover/core/kernel.hpp | 3 ++
src/gallium/state_trackers/clover/core/module.hpp | 13 ++++--
src/gallium/state_trackers/clover/core/program.cpp | 4 +-
.../state_trackers/clover/llvm/invocation.cpp | 53 ++++++++++++++++++----
.../state_trackers/clover/tgsi/compiler.cpp | 27 +++++++----
7 files changed, 91 insertions(+), 28 deletions(-)
diff --git a/src/gallium/state_trackers/clover/core/compiler.hpp b/src/gallium/state_trackers/clover/core/compiler.hpp
index b8af1c8..b1df312 100644
--- a/src/gallium/state_trackers/clover/core/compiler.hpp
+++ b/src/gallium/state_trackers/clover/core/compiler.hpp
@@ -54,8 +54,7 @@ namespace clover {
};
module compile_program_llvm(const compat::string &source,
- enum pipe_shader_ir ir,
- const compat::string &target,
+ const struct pipe_screen *pipe,
const compat::string &opts);
module compile_program_tgsi(const compat::string &source);
diff --git a/src/gallium/state_trackers/clover/core/kernel.cpp b/src/gallium/state_trackers/clover/core/kernel.cpp
index c95285d..2b6fbe5 100644
--- a/src/gallium/state_trackers/clover/core/kernel.cpp
+++ b/src/gallium/state_trackers/clover/core/kernel.cpp
@@ -31,6 +31,8 @@ _cl_kernel::_cl_kernel(clover::program &prog,
const std::vector<clover::module::argument> &args) :
prog(prog), __name(name), exec(*this) {
for (auto arg : args) {
+ if (arg.type == module::argument::pad)
+ continue;
if (arg.type == module::argument::scalar)
this->args.emplace_back(new scalar_argument(arg.size));
else if (arg.type == module::argument::global)
@@ -129,6 +131,10 @@ _cl_kernel::module(const clover::command_queue &q) const {
return prog.binaries().find(&q.dev)->second;
}
+const clover::compat::vector<clover::module::argument> &
+_cl_kernel::module_args(const clover::command_queue &q) const {
+ return module(q).sym(__name).args;
+}
_cl_kernel::exec_context::exec_context(clover::kernel &kern) :
kern(kern), q(NULL), mem_local(0), st(NULL) {
@@ -143,8 +149,14 @@ void *
_cl_kernel::exec_context::bind(clover::command_queue *__q) {
std::swap(q, __q);
- for (auto &arg : kern.args)
- arg->bind(*this);
+ for (const clover::module::argument &arg : kern.module_args(*q)) {
+ if (arg.type == clover::module::argument::pad) {
+ input.resize(input.size() + arg.size);
+ } else {
+ assert(arg.arg_index >= 0);
+ kern.args[arg.arg_index]->bind(*this);
+ }
+ }
// Create a new compute state if anything changed.
if (!st || q != __q ||
diff --git a/src/gallium/state_trackers/clover/core/kernel.hpp b/src/gallium/state_trackers/clover/core/kernel.hpp
index 6b336d0..2c540be 100644
--- a/src/gallium/state_trackers/clover/core/kernel.hpp
+++ b/src/gallium/state_trackers/clover/core/kernel.hpp
@@ -117,6 +117,9 @@ private:
const clover::module &
module(const clover::command_queue &q) const;
+ const clover::compat::vector<clover::module::argument> &
+ module_args(const clover::command_queue &q) const;
+
class scalar_argument : public argument {
public:
scalar_argument(size_t size);
diff --git a/src/gallium/state_trackers/clover/core/module.hpp b/src/gallium/state_trackers/clover/core/module.hpp
index 88dfc9f..d4b3413 100644
--- a/src/gallium/state_trackers/clover/core/module.hpp
+++ b/src/gallium/state_trackers/clover/core/module.hpp
@@ -65,14 +65,21 @@ namespace clover {
image2d_wr,
image3d_rd,
image3d_wr,
- sampler
+ sampler,
+ pad
};
- argument(enum type type, size_t size) : type(type), size(size) { }
- argument() : type(scalar), size(0) { }
+ argument(enum type type, size_t size, size_t arg_index) : type(type),
+ size(size), arg_index(arg_index) { }
+ argument(enum type type, size_t size) : type(type), size(size),
+ arg_index(-1) { }
+ argument() : type(scalar), size(0), arg_index(-1) { }
type type;
size_t size;
+ /// The index of this argument in the function. If arg_index is -1,
+ /// then this arguement is not a formal argument of the function.
+ size_t arg_index;
};
struct symbol {
diff --git a/src/gallium/state_trackers/clover/core/program.cpp b/src/gallium/state_trackers/clover/core/program.cpp
index e85f27a..1e5a126 100644
--- a/src/gallium/state_trackers/clover/core/program.cpp
+++ b/src/gallium/state_trackers/clover/core/program.cpp
@@ -53,8 +53,8 @@ _cl_program::build(const std::vector<clover::device *> &devs,
try {
auto module = (dev->ir_format() == PIPE_SHADER_IR_TGSI ?
compile_program_tgsi(__source) :
- compile_program_llvm(__source, dev->ir_format(),
- dev->ir_target(), build_opts(dev)));
+ compile_program_llvm(__source, dev->get_pipe(),
+ build_opts(dev)));
__binaries.insert({ dev, module });
} catch (build_error &e) {
diff --git a/src/gallium/state_trackers/clover/llvm/invocation.cpp b/src/gallium/state_trackers/clover/llvm/invocation.cpp
index dae61f7..68f7eac 100644
--- a/src/gallium/state_trackers/clover/llvm/invocation.cpp
+++ b/src/gallium/state_trackers/clover/llvm/invocation.cpp
@@ -20,6 +20,7 @@
// OTHER DEALINGS IN THE SOFTWARE.
//
+#include "pipe/p_screen.h"
#include "core/compiler.hpp"
#include <clang/Frontend/CompilerInstance.h>
@@ -58,6 +59,7 @@
#endif
#include "pipe/p_state.h"
+#include "util/u_math.h"
#include "util/u_memory.h"
#include <iostream>
@@ -282,6 +284,7 @@ namespace {
module
build_module_llvm(llvm::Module *mod,
+ const struct pipe_screen *pipe,
const std::vector<llvm::Function *> &kernels) {
module m;
@@ -311,6 +314,18 @@ namespace {
llvm::DataLayout TD(kernel_func->getParent()->getDataLayout());
#endif
unsigned arg_size = TD.getTypeStoreSize(arg_type);
+ size_t alignment = arg_size;
+ pipe->get_compute_param(pipe, PIPE_COMPUTE_CAP_KERNEL_ARG_ALIGNMENT,
+ &alignment);
+ unsigned aligned_size = align(arg_size, alignment);
+ size_t target_size;
+ if (arg_type->isIntegerTy()) {
+ llvm::Type *target_type = TD.getSmallestLegalIntType(
+ mod->getContext(), arg_type->getPrimitiveSizeInBits());
+ target_size = target_type->getPrimitiveSizeInBits();
+ } else {
+ target_size = aligned_size;
+ }
if (llvm::isa<llvm::PointerType>(arg_type) && arg.hasByValAttr()) {
arg_type =
@@ -324,11 +339,17 @@ namespace {
unsigned address_space = llvm::cast<llvm::PointerType>(arg_type)->getAddressSpace();
switch (address_space) {
default:
- args.push_back(module::argument(module::argument::global, arg_size));
+ args.push_back(module::argument(module::argument::global,
+ arg_size, arg.getArgNo()));
break;
}
} else {
- args.push_back(module::argument(module::argument::scalar, arg_size));
+ args.push_back(module::argument(module::argument::scalar,
+ arg_size, arg.getArgNo()));
+ }
+ if (aligned_size > target_size) {
+ args.push_back(module::argument(module::argument::pad,
+ aligned_size - target_size));
}
}
@@ -349,15 +370,24 @@ namespace {
module
clover::compile_program_llvm(const compat::string &source,
- enum pipe_shader_ir ir,
- const compat::string &target,
+ const struct pipe_screen *pipe,
const compat::string &opts) {
std::vector<llvm::Function *> kernels;
- size_t processor_str_len = std::string(target.begin()).find_first_of("-");
- std::string processor(target.begin(), 0, processor_str_len);
- std::string triple(target.begin(), processor_str_len + 1,
- target.size() - processor_str_len - 1);
+ enum pipe_shader_ir ir = (enum pipe_shader_ir) pipe->get_shader_param(pipe,
+ PIPE_SHADER_COMPUTE,
+ PIPE_SHADER_CAP_PREFERRED_IR);
+ size_t target_str_len = pipe->get_compute_param(pipe,
+ PIPE_COMPUTE_CAP_IR_TARGET, NULL);
+ char *target = (char*)MALLOC(target_str_len);
+ pipe->get_compute_param(pipe, PIPE_COMPUTE_CAP_IR_TARGET, target);
+
+ size_t processor_str_len = strchr(target, '-') - target;
+ char *triple_start = target + processor_str_len + 1;
+ size_t triple_str_len = strlen(target) - processor_str_len - 1;
+
+ std::string processor(target, processor_str_len);
+ std::string triple(triple_start, triple_str_len);
// The input file name must have the .cl extension in order for the
// CompilerInvocation class to recognize it as an OpenCL source file.
@@ -367,13 +397,16 @@ clover::compile_program_llvm(const compat::string &source,
link(mod, triple, processor, kernels);
+ module clover_mod;
// Build the clover::module
switch (ir) {
case PIPE_SHADER_IR_TGSI:
//XXX: Handle TGSI
assert(0);
- return module();
+ clover_mod = module();
default:
- return build_module_llvm(mod, kernels);
+ clover_mod = build_module_llvm(mod, pipe, kernels);
}
+ FREE(target);
+ return clover_mod;
}
diff --git a/src/gallium/state_trackers/clover/tgsi/compiler.cpp b/src/gallium/state_trackers/clover/tgsi/compiler.cpp
index 93dfeb5..698c504 100644
--- a/src/gallium/state_trackers/clover/tgsi/compiler.cpp
+++ b/src/gallium/state_trackers/clover/tgsi/compiler.cpp
@@ -50,23 +50,32 @@ namespace {
while (ts >> tok) {
if (tok == "scalar")
- args.push_back({ module::argument::scalar, 4 });
+ args.push_back({ module::argument::scalar, 4,
+ (module::size_t) args.size() });
else if (tok == "global")
- args.push_back({ module::argument::global, 4 });
+ args.push_back({ module::argument::global, 4,
+ (module::size_t) args.size() });
else if (tok == "local")
- args.push_back({ module::argument::local, 4 });
+ args.push_back({ module::argument::local, 4,
+ (module::size_t) args.size() });
else if (tok == "constant")
- args.push_back({ module::argument::constant, 4 });
+ args.push_back({ module::argument::constant, 4,
+ (module::size_t) args.size() });
else if (tok == "image2d_rd")
- args.push_back({ module::argument::image2d_rd, 4 });
+ args.push_back({ module::argument::image2d_rd, 4,
+ (module::size_t) args.size() });
else if (tok == "image2d_wr")
- args.push_back({ module::argument::image2d_wr, 4 });
+ args.push_back({ module::argument::image2d_wr, 4,
+ (module::size_t) args.size() });
else if (tok == "image3d_rd")
- args.push_back({ module::argument::image3d_rd, 4 });
+ args.push_back({ module::argument::image3d_rd, 4,
+ (module::size_t) args.size() });
else if (tok == "image3d_wr")
- args.push_back({ module::argument::image3d_wr, 4 });
+ args.push_back({ module::argument::image3d_wr, 4,
+ (module::size_t) args.size() });
else if (tok == "sampler")
- args.push_back({ module::argument::sampler, 0 });
+ args.push_back({ module::argument::sampler, 0,
+ (module::size_t) args.size() });
else
throw build_error("invalid kernel argument");
}
--
1.7.11.4
More information about the mesa-dev
mailing list