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 26using 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 41void 42_cl_mem::destroy_notify(std::function<void ()> f) { 43 __destroy_notify = f; 44} 45 46cl_mem_flags 47_cl_mem::flags() const { 48 return __flags; 49} 50 51size_t 52_cl_mem::size() const { 53 return __size; 54} 55 56void * 57_cl_mem::host_ptr() const { 58 return __host_ptr; 59} 60 61buffer::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 66cl_mem_object_type 67buffer::type() const { 68 return CL_MEM_OBJECT_BUFFER; 69} 70 71root_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 76clover::resource & 77root_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 92sub_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 99clover::resource & 100sub_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 112size_t 113sub_buffer::offset() const { 114 return __offset; 115} 116 117image::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 127clover::resource & 128image::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 143cl_image_format 144image::format() const { 145 return __format; 146} 147 148size_t 149image::width() const { 150 return __width; 151} 152 153size_t 154image::height() const { 155 return __height; 156} 157 158size_t 159image::depth() const { 160 return __depth; 161} 162 163size_t 164image::row_pitch() const { 165 return __row_pitch; 166} 167 168size_t 169image::slice_pitch() const { 170 return __slice_pitch; 171} 172 173image2d::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 181cl_mem_object_type 182image2d::type() const { 183 return CL_MEM_OBJECT_IMAGE2D; 184} 185 186image3d::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 196cl_mem_object_type 197image3d::type() const { 198 return CL_MEM_OBJECT_IMAGE3D; 199} 200