clover: Extend kernel arguments for differing host and device data types.
Loosely based on a similar patch by Tom Stellard. Cc: mesa-stable@lists.freedesktop.org Reviewed-by: Tom Stellard <thomas.stellard@amd.com>
This commit is contained in:
@@ -197,6 +197,34 @@ namespace {
|
||||
std::reverse(v.begin(), v.end());
|
||||
}
|
||||
|
||||
bool
|
||||
msb(const std::vector<uint8_t> &s) {
|
||||
if (PIPE_ENDIAN_NATIVE == PIPE_ENDIAN_LITTLE)
|
||||
return s.back() & 0x80;
|
||||
else
|
||||
return s.front() & 0x80;
|
||||
}
|
||||
|
||||
///
|
||||
/// Resize buffer \a v to size \a n using sign or zero extension
|
||||
/// according to \a ext.
|
||||
///
|
||||
template<typename T>
|
||||
void
|
||||
extend(T &v, enum clover::module::argument::ext_type ext, size_t n) {
|
||||
const size_t m = std::min(v.size(), n);
|
||||
const bool sign_ext = (ext == module::argument::sign_ext);
|
||||
const uint8_t fill = (sign_ext && msb(v) ? ~0 : 0);
|
||||
T w(n, fill);
|
||||
|
||||
if (PIPE_ENDIAN_NATIVE == PIPE_ENDIAN_LITTLE)
|
||||
std::copy_n(v.begin(), m, w.begin());
|
||||
else
|
||||
std::copy_n(v.end() - m, m, w.end() - m);
|
||||
|
||||
std::swap(v, w);
|
||||
}
|
||||
|
||||
///
|
||||
/// Append buffer \a w to \a v.
|
||||
///
|
||||
@@ -248,6 +276,7 @@ _cl_kernel::scalar_argument::bind(exec_context &ctx,
|
||||
const clover::module::argument &marg) {
|
||||
auto w = v;
|
||||
|
||||
extend(w, marg.ext_type, marg.target_size);
|
||||
byteswap(w, ctx.q->dev.endianness());
|
||||
insert(ctx.input, w);
|
||||
}
|
||||
@@ -271,7 +300,7 @@ _cl_kernel::global_argument::set(size_t size, const void *value) {
|
||||
void
|
||||
_cl_kernel::global_argument::bind(exec_context &ctx,
|
||||
const clover::module::argument &marg) {
|
||||
ctx.g_handles.push_back(allocate(ctx.input, marg.size));
|
||||
ctx.g_handles.push_back(allocate(ctx.input, marg.target_size));
|
||||
ctx.g_buffers.push_back(obj->resource(ctx.q).pipe);
|
||||
}
|
||||
|
||||
@@ -298,6 +327,7 @@ _cl_kernel::local_argument::bind(exec_context &ctx,
|
||||
const clover::module::argument &marg) {
|
||||
auto v = bytes(ctx.mem_local);
|
||||
|
||||
extend(v, module::argument::zero_ext, marg.target_size);
|
||||
byteswap(v, ctx.q->dev.endianness());
|
||||
insert(ctx.input, v);
|
||||
|
||||
@@ -325,6 +355,7 @@ _cl_kernel::constant_argument::bind(exec_context &ctx,
|
||||
const clover::module::argument &marg) {
|
||||
auto v = bytes(ctx.resources.size() << 24);
|
||||
|
||||
extend(v, module::argument::zero_ext, marg.target_size);
|
||||
byteswap(v, ctx.q->dev.endianness());
|
||||
insert(ctx.input, v);
|
||||
|
||||
@@ -354,6 +385,7 @@ _cl_kernel::image_rd_argument::bind(exec_context &ctx,
|
||||
const clover::module::argument &marg) {
|
||||
auto v = bytes(ctx.sviews.size());
|
||||
|
||||
extend(v, module::argument::zero_ext, marg.target_size);
|
||||
byteswap(v, ctx.q->dev.endianness());
|
||||
insert(ctx.input, v);
|
||||
|
||||
@@ -383,6 +415,7 @@ _cl_kernel::image_wr_argument::bind(exec_context &ctx,
|
||||
const clover::module::argument &marg) {
|
||||
auto v = bytes(ctx.resources.size());
|
||||
|
||||
extend(v, module::argument::zero_ext, marg.target_size);
|
||||
byteswap(v, ctx.q->dev.endianness());
|
||||
insert(ctx.input, v);
|
||||
|
||||
|
@@ -304,14 +304,20 @@ namespace {
|
||||
for (llvm::Function::arg_iterator I = kernel_func->arg_begin(),
|
||||
E = kernel_func->arg_end(); I != E; ++I) {
|
||||
llvm::Argument &arg = *I;
|
||||
llvm::Type *arg_type = arg.getType();
|
||||
#if HAVE_LLVM < 0x0302
|
||||
llvm::TargetData TD(kernel_func->getParent());
|
||||
#else
|
||||
llvm::DataLayout TD(kernel_func->getParent()->getDataLayout());
|
||||
#endif
|
||||
|
||||
llvm::Type *arg_type = arg.getType();
|
||||
unsigned arg_size = TD.getTypeStoreSize(arg_type);
|
||||
|
||||
llvm::Type *target_type = arg_type->isIntegerTy() ?
|
||||
TD.getSmallestLegalIntType(mod->getContext(), arg_size * 8) :
|
||||
arg_type;
|
||||
unsigned target_size = TD.getTypeStoreSize(target_type);
|
||||
|
||||
if (llvm::isa<llvm::PointerType>(arg_type) && arg.hasByValAttr()) {
|
||||
arg_type =
|
||||
llvm::dyn_cast<llvm::PointerType>(arg_type)->getElementType();
|
||||
@@ -324,11 +330,24 @@ 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,
|
||||
target_size, 0,
|
||||
module::argument::zero_ext));
|
||||
break;
|
||||
}
|
||||
|
||||
} else {
|
||||
args.push_back(module::argument(module::argument::scalar, arg_size));
|
||||
llvm::AttributeSet attrs = kernel_func->getAttributes();
|
||||
enum module::argument::ext_type ext_type =
|
||||
(attrs.hasAttribute(arg.getArgNo() + 1,
|
||||
llvm::Attribute::SExt) ?
|
||||
module::argument::sign_ext :
|
||||
module::argument::zero_ext);
|
||||
|
||||
args.push_back(
|
||||
module::argument(module::argument::scalar, arg_size,
|
||||
target_size, 0, ext_type));
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user