clover: Fix region size error checking in some buffer transfer commands.
authorFrancisco Jerez <currojerez@riseup.net>
Fri, 14 Mar 2014 10:31:11 +0000 (11:31 +0100)
committerFrancisco Jerez <currojerez@riseup.net>
Tue, 18 Mar 2014 11:14:46 +0000 (12:14 +0100)
Tested-by: Tom Stellard <thomas.stellard@amd.com>
src/gallium/state_trackers/clover/api/transfer.cpp

index 72f0b3041a9dbd6a1b49a4fcf2bad60e759f7a9d..e41b7f24f82dfb88e22f49bf04b354a3726f4683 100644 (file)
@@ -49,6 +49,17 @@ namespace {
       return pitch;
    }
 
+   ///
+   /// Size of a region in bytes.
+   ///
+   size_t
+   size(const vector_t &pitch, const vector_t &region) {
+      if (any_of(is_zero(), region))
+         return 0;
+      else
+         return dot(pitch, region - vector_t{ 0, 1, 1 });
+   }
+
    ///
    /// Common argument checking shared by memory transfer commands.
    ///
@@ -75,7 +86,7 @@ namespace {
          throw error(CL_INVALID_VALUE);
 
       // ...and within the specified object.
-      if (dot(pitch, origin) + pitch[2] * region[2] > mem.size())
+      if (dot(pitch, origin) + size(pitch, origin) > mem.size())
          throw error(CL_INVALID_VALUE);
 
       if (any_of(is_zero(), region))
@@ -128,8 +139,8 @@ namespace {
          auto src_offset = dot(src_pitch, src_orig);
 
          if (interval_overlaps()(
-                dst_offset, dst_offset + dst_pitch[2] * region[2],
-                src_offset, src_offset + src_pitch[2] * region[2]))
+                dst_offset, dst_offset + size(dst_pitch, region),
+                src_offset, src_offset + size(src_pitch, region)))
             throw error(CL_MEM_COPY_OVERLAP);
       }
    }
@@ -199,10 +210,10 @@ namespace {
       return [=, &q](event &) {
          auto dst = _map<T>::get(q, dst_obj, CL_MAP_WRITE,
                                  dot(dst_pitch, dst_orig),
-                                 dst_pitch[2] * region[2]);
+                                 size(dst_pitch, region));
          auto src = _map<S>::get(q, src_obj, CL_MAP_READ,
                                  dot(src_pitch, src_orig),
-                                 src_pitch[2] * region[2]);
+                                 size(src_pitch, region));
          vector_t v = {};
 
          for (v[2] = 0; v[2] < region[2]; ++v[2]) {