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 OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
     18 // OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     19 // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     20 // OTHER DEALINGS IN THE SOFTWARE.
     21 //
     22 
     23 #include "core/memory.hpp"
     24 #include "core/resource.hpp"
     25 #include "util/u_format.h"
     26 
     27 using namespace clover;
     28 
     29 memory_obj::memory_obj(clover::context &ctx, cl_mem_flags flags,
     30                        size_t size, void *host_ptr) :
     31    context(ctx), _flags(flags),
     32    _size(size), _host_ptr(host_ptr) {
     33    if (flags & CL_MEM_COPY_HOST_PTR)
     34       data.append((char *)host_ptr, size);
     35 }
     36 
     37 memory_obj::~memory_obj() {
     38    while (_destroy_notify.size()) {
     39       _destroy_notify.top()();
     40       _destroy_notify.pop();
     41    }
     42 }
     43 
     44 bool
     45 memory_obj::operator==(const memory_obj &obj) const {
     46    return this == &obj;
     47 }
     48 
     49 void
     50 memory_obj::destroy_notify(std::function<void ()> f) {
     51    _destroy_notify.push(f);
     52 }
     53 
     54 cl_mem_flags
     55 memory_obj::flags() const {
     56    return _flags;
     57 }
     58 
     59 size_t
     60 memory_obj::size() const {
     61    return _size;
     62 }
     63 
     64 void *
     65 memory_obj::host_ptr() const {
     66    return _host_ptr;
     67 }
     68 
     69 buffer::buffer(clover::context &ctx, cl_mem_flags flags,
     70                size_t size, void *host_ptr) :
     71    memory_obj(ctx, flags, size, host_ptr) {
     72 }
     73 
     74 cl_mem_object_type
     75 buffer::type() const {
     76    return CL_MEM_OBJECT_BUFFER;
     77 }
     78 
     79 root_buffer::root_buffer(clover::context &ctx, cl_mem_flags flags,
     80                          size_t size, void *host_ptr) :
     81    buffer(ctx, flags, size, host_ptr) {
     82 }
     83 
     84 resource &
     85 root_buffer::resource(command_queue &q) {
     86    // Create a new resource if there's none for this device yet.
     87    if (!resources.count(&q.device())) {
     88       auto r = (!resources.empty() ?
     89                 new root_resource(q.device(), *this,
     90                                   *resources.begin()->second) :
     91                 new root_resource(q.device(), *this, q, data));
     92 
     93       resources.insert(std::make_pair(&q.device(),
     94                                       std::unique_ptr<root_resource>(r)));
     95       data.clear();
     96    }
     97 
     98    return *resources.find(&q.device())->second;
     99 }
    100 
    101 sub_buffer::sub_buffer(root_buffer &parent, cl_mem_flags flags,
    102                        size_t offset, size_t size) :
    103    buffer(parent.context(), flags, size,
    104           (char *)parent.host_ptr() + offset),
    105    parent(parent), _offset(offset) {
    106 }
    107 
    108 resource &
    109 sub_buffer::resource(command_queue &q) {
    110    // Create a new resource if there's none for this device yet.
    111    if (!resources.count(&q.device())) {
    112       auto r = new sub_resource(parent().resource(q), {{ offset() }});
    113 
    114       resources.insert(std::make_pair(&q.device(),
    115                                       std::unique_ptr<sub_resource>(r)));
    116    }
    117 
    118    return *resources.find(&q.device())->second;
    119 }
    120 
    121 size_t
    122 sub_buffer::offset() const {
    123    return _offset;
    124 }
    125 
    126 image::image(clover::context &ctx, cl_mem_flags flags,
    127              const cl_image_format *format,
    128              size_t width, size_t height, size_t depth,
    129              size_t row_pitch, size_t slice_pitch, size_t size,
    130              void *host_ptr) :
    131    memory_obj(ctx, flags, size, host_ptr),
    132    _format(*format), _width(width), _height(height), _depth(depth),
    133    _row_pitch(row_pitch), _slice_pitch(slice_pitch) {
    134 }
    135 
    136 resource &
    137 image::resource(command_queue &q) {
    138    // Create a new resource if there's none for this device yet.
    139    if (!resources.count(&q.device())) {
    140       auto r = (!resources.empty() ?
    141                 new root_resource(q.device(), *this,
    142                                   *resources.begin()->second) :
    143                 new root_resource(q.device(), *this, q, data));
    144 
    145       resources.insert(std::make_pair(&q.device(),
    146                                       std::unique_ptr<root_resource>(r)));
    147       data.clear();
    148    }
    149 
    150    return *resources.find(&q.device())->second;
    151 }
    152 
    153 cl_image_format
    154 image::format() const {
    155    return _format;
    156 }
    157 
    158 size_t
    159 image::width() const {
    160    return _width;
    161 }
    162 
    163 size_t
    164 image::height() const {
    165    return _height;
    166 }
    167 
    168 size_t
    169 image::depth() const {
    170    return _depth;
    171 }
    172 
    173 size_t
    174 image::pixel_size() const {
    175    return util_format_get_blocksize(translate_format(_format));
    176 }
    177 
    178 size_t
    179 image::row_pitch() const {
    180    return _row_pitch;
    181 }
    182 
    183 size_t
    184 image::slice_pitch() const {
    185    return _slice_pitch;
    186 }
    187 
    188 image2d::image2d(clover::context &ctx, cl_mem_flags flags,
    189                  const cl_image_format *format, size_t width,
    190                  size_t height, size_t row_pitch,
    191                  void *host_ptr) :
    192    image(ctx, flags, format, width, height, 1,
    193          row_pitch, 0, height * row_pitch, host_ptr) {
    194 }
    195 
    196 cl_mem_object_type
    197 image2d::type() const {
    198    return CL_MEM_OBJECT_IMAGE2D;
    199 }
    200 
    201 image3d::image3d(clover::context &ctx, cl_mem_flags flags,
    202                  const cl_image_format *format,
    203                  size_t width, size_t height, size_t depth,
    204                  size_t row_pitch, size_t slice_pitch,
    205                  void *host_ptr) :
    206    image(ctx, flags, format, width, height, depth,
    207          row_pitch, slice_pitch, depth * slice_pitch,
    208          host_ptr) {
    209 }
    210 
    211 cl_mem_object_type
    212 image3d::type() const {
    213    return CL_MEM_OBJECT_IMAGE3D;
    214 }
    215