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