Mesa (master): clover: Extend kernel arguments for differing host and device data types.

Francisco Jerez currojerez at kemper.freedesktop.org
Mon Jul 22 21:20:57 UTC 2013


Module: Mesa
Branch: master
Commit: f64c0ca692d3e8c78dd9ae1f015f58f1dfc1c760
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=f64c0ca692d3e8c78dd9ae1f015f58f1dfc1c760

Author: Francisco Jerez <currojerez at riseup.net>
Date:   Mon Jul 22 23:08:46 2013 +0200

clover: Extend kernel arguments for differing host and device data types.

Loosely based on a similar patch by Tom Stellard.

Cc: mesa-stable at lists.freedesktop.org
Reviewed-by: Tom Stellard <thomas.stellard at amd.com>

---

 src/gallium/state_trackers/clover/core/kernel.cpp  |   35 +++++++++++++++++++-
 .../state_trackers/clover/llvm/invocation.cpp      |   25 ++++++++++++--
 2 files changed, 56 insertions(+), 4 deletions(-)

diff --git a/src/gallium/state_trackers/clover/core/kernel.cpp b/src/gallium/state_trackers/clover/core/kernel.cpp
index 82e937e..7023f29 100644
--- a/src/gallium/state_trackers/clover/core/kernel.cpp
+++ b/src/gallium/state_trackers/clover/core/kernel.cpp
@@ -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);
 
diff --git a/src/gallium/state_trackers/clover/llvm/invocation.cpp b/src/gallium/state_trackers/clover/llvm/invocation.cpp
index dae61f7..a50cf37 100644
--- a/src/gallium/state_trackers/clover/llvm/invocation.cpp
+++ b/src/gallium/state_trackers/clover/llvm/invocation.cpp
@@ -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));
             }
          }
 




More information about the mesa-commit mailing list