Home | History | Annotate | Download | only in core
      1 //
      2 // Copyright 2012 Francisco Jerez
      3 //
      4 // Permission is hereby granted, free of charge, to any person obtaining a
      5 // copy of this software and associated documentation files (the "Software"),
      6 // to deal in the Software without restriction, including without limitation
      7 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
      8 // and/or sell copies of the Software, and to permit persons to whom the
      9 // Software is furnished to do so, subject to the following conditions:
     10 //
     11 // The above copyright notice and this permission notice shall be included in
     12 // all copies or substantial portions of the Software.
     13 //
     14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     17 // THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
     18 // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
     19 // OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     20 // SOFTWARE.
     21 //
     22 
     23 #include "core/memory.hpp"
     24 #include "core/resource.hpp"
     25 
     26 using namespace clover;
     27 
     28 _cl_mem::_cl_mem(clover::context &ctx, cl_mem_flags flags,
     29                  size_t size, void *host_ptr) :
     30    ctx(ctx), __flags(flags),
     31    __size(size), __host_ptr(host_ptr),
     32    __destroy_notify([]{}) {
     33    if (flags & CL_MEM_COPY_HOST_PTR)
     34       data.append((char *)host_ptr, size);
     35 }
     36 
     37 _cl_mem::~_cl_mem() {
     38    __destroy_notify();
     39 }
     40 
     41 void
     42 _cl_mem::destroy_notify(std::function<void ()> f) {
     43    __destroy_notify = f;
     44 }
     45 
     46 cl_mem_flags
     47 _cl_mem::flags() const {
     48    return __flags;
     49 }
     50 
     51 size_t
     52 _cl_mem::size() const {
     53    return __size;
     54 }
     55 
     56 void *
     57 _cl_mem::host_ptr() const {
     58    return __host_ptr;
     59 }
     60 
     61 buffer::buffer(clover::context &ctx, cl_mem_flags flags,
     62                size_t size, void *host_ptr) :
     63    memory_obj(ctx, flags, size, host_ptr) {
     64 }
     65 
     66 cl_mem_object_type
     67 buffer::type() const {
     68    return CL_MEM_OBJECT_BUFFER;
     69 }
     70 
     71 root_buffer::root_buffer(clover::context &ctx, cl_mem_flags flags,
     72                          size_t size, void *host_ptr) :
     73    buffer(ctx, flags, size, host_ptr) {
     74 }
     75 
     76 clover::resource &
     77 root_buffer::resource(cl_command_queue q) {
     78    // Create a new resource if there's none for this device yet.
     79    if (!resources.count(&q->dev)) {
     80       auto r = (!resources.empty() ?
     81                 new root_resource(q->dev, *this, *resources.begin()->second) :
     82                 new root_resource(q->dev, *this, *q, data));
     83 
     84       resources.insert(std::make_pair(&q->dev,
     85                                       std::unique_ptr<root_resource>(r)));
     86       data.clear();
     87    }
     88 
     89    return *resources.find(&q->dev)->second;
     90 }
     91 
     92 sub_buffer::sub_buffer(clover::root_buffer &parent, cl_mem_flags flags,
     93                        size_t offset, size_t size) :
     94    buffer(parent.ctx, flags, size,
     95           (char *)parent.host_ptr() + offset),
     96    parent(parent), __offset(offset) {
     97 }
     98 
     99 clover::resource &
    100 sub_buffer::resource(cl_command_queue q) {
    101    // Create a new resource if there's none for this device yet.
    102    if (!resources.count(&q->dev)) {
    103       auto r = new sub_resource(parent.resource(q), { offset() });
    104 
    105       resources.insert(std::make_pair(&q->dev,
    106                                       std::unique_ptr<sub_resource>(r)));
    107    }
    108 
    109    return *resources.find(&q->dev)->second;
    110 }
    111 
    112 size_t
    113 sub_buffer::offset() const {
    114    return __offset;
    115 }
    116 
    117 image::image(clover::context &ctx, cl_mem_flags flags,
    118              const cl_image_format *format,
    119              size_t width, size_t height, size_t depth,
    120              size_t row_pitch, size_t slice_pitch, size_t size,
    121              void *host_ptr) :
    122    memory_obj(ctx, flags, size, host_ptr),
    123    __format(*format), __width(width), __height(height), __depth(depth),
    124    __row_pitch(row_pitch), __slice_pitch(slice_pitch) {
    125 }
    126 
    127 clover::resource &
    128 image::resource(cl_command_queue q) {
    129    // Create a new resource if there's none for this device yet.
    130    if (!resources.count(&q->dev)) {
    131       auto r = (!resources.empty() ?
    132                 new root_resource(q->dev, *this, *resources.begin()->second) :
    133                 new root_resource(q->dev, *this, *q, data));
    134 
    135       resources.insert(std::make_pair(&q->dev,
    136                                       std::unique_ptr<root_resource>(r)));
    137       data.clear();
    138    }
    139 
    140    return *resources.find(&q->dev)->second;
    141 }
    142 
    143 cl_image_format
    144 image::format() const {
    145    return __format;
    146 }
    147 
    148 size_t
    149 image::width() const {
    150    return __width;
    151 }
    152 
    153 size_t
    154 image::height() const {
    155    return __height;
    156 }
    157 
    158 size_t
    159 image::depth() const {
    160    return __depth;
    161 }
    162 
    163 size_t
    164 image::row_pitch() const {
    165    return __row_pitch;
    166 }
    167 
    168 size_t
    169 image::slice_pitch() const {
    170    return __slice_pitch;
    171 }
    172 
    173 image2d::image2d(clover::context &ctx, cl_mem_flags flags,
    174                  const cl_image_format *format, size_t width,
    175                  size_t height, size_t row_pitch,
    176                  void *host_ptr) :
    177    image(ctx, flags, format, width, height, 0,
    178          row_pitch, 0, height * row_pitch, host_ptr) {
    179 }
    180 
    181 cl_mem_object_type
    182 image2d::type() const {
    183    return CL_MEM_OBJECT_IMAGE2D;
    184 }
    185 
    186 image3d::image3d(clover::context &ctx, cl_mem_flags flags,
    187                  const cl_image_format *format,
    188                  size_t width, size_t height, size_t depth,
    189                  size_t row_pitch, size_t slice_pitch,
    190                  void *host_ptr) :
    191    image(ctx, flags, format, width, height, depth,
    192          row_pitch, slice_pitch, depth * slice_pitch,
    193          host_ptr) {
    194 }
    195 
    196 cl_mem_object_type
    197 image3d::type() const {
    198    return CL_MEM_OBJECT_IMAGE3D;
    199 }
    200