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 #ifndef CLOVER_CORE_MEMORY_HPP 24 #define CLOVER_CORE_MEMORY_HPP 25 26 #include <functional> 27 #include <map> 28 #include <memory> 29 #include <stack> 30 31 #include "core/object.hpp" 32 #include "core/queue.hpp" 33 #include "core/resource.hpp" 34 35 namespace clover { 36 class memory_obj : public ref_counter, public _cl_mem { 37 protected: 38 memory_obj(clover::context &ctx, 39 std::vector<cl_mem_properties> properties, 40 cl_mem_flags flags, 41 size_t size, void *host_ptr); 42 43 memory_obj(const memory_obj &obj) = delete; 44 memory_obj & 45 operator=(const memory_obj &obj) = delete; 46 47 public: 48 virtual ~memory_obj(); 49 50 bool 51 operator==(const memory_obj &obj) const; 52 53 virtual cl_mem_object_type type() const = 0; 54 virtual clover::resource & 55 resource_in(command_queue &q) = 0; 56 virtual clover::resource & 57 resource_undef(command_queue &q) = 0; 58 virtual void resource_out(command_queue &q) = 0; 59 60 void destroy_notify(std::function<void ()> f); 61 std::vector<cl_mem_properties> properties() const; 62 cl_mem_flags flags() const; 63 size_t size() const; 64 void *host_ptr() const; 65 66 const intrusive_ref<clover::context> context; 67 68 private: 69 std::vector<cl_mem_properties> _properties; 70 cl_mem_flags _flags; 71 size_t _size; 72 void *_host_ptr; 73 std::stack<std::function<void ()>> _destroy_notify; 74 75 protected: 76 std::string data; 77 }; 78 79 class buffer : public memory_obj { 80 protected: 81 buffer(clover::context &ctx, 82 std::vector<cl_mem_properties> properties, 83 cl_mem_flags flags, 84 size_t size, void *host_ptr); 85 86 public: 87 virtual cl_mem_object_type type() const; 88 }; 89 90 class root_buffer : public buffer { 91 public: 92 root_buffer(clover::context &ctx, 93 std::vector<cl_mem_properties> properties, 94 cl_mem_flags flags, 95 size_t size, void *host_ptr); 96 97 virtual clover::resource & 98 resource_in(command_queue &q); 99 virtual clover::resource & 100 resource_undef(command_queue &q); 101 virtual void 102 resource_out(command_queue &q); 103 104 private: 105 clover::resource & 106 resource(command_queue &q, const void *data_ptr); 107 108 std::map<device *, 109 std::unique_ptr<root_resource>> resources; 110 std::mutex resources_mtx; 111 }; 112 113 class sub_buffer : public buffer { 114 public: 115 sub_buffer(root_buffer &parent, cl_mem_flags flags, 116 size_t offset, size_t size); 117 118 virtual clover::resource & 119 resource_in(command_queue &q); 120 virtual clover::resource & 121 resource_undef(command_queue &q); 122 virtual void 123 resource_out(command_queue &q); 124 size_t offset() const; 125 126 const intrusive_ref<root_buffer> parent; 127 128 private: 129 size_t _offset; 130 std::map<device *, 131 std::unique_ptr<sub_resource>> resources; 132 std::mutex resources_mtx; 133 }; 134 135 class image : public memory_obj { 136 protected: 137 image(clover::context &ctx, 138 std::vector<cl_mem_properties> properties, 139 cl_mem_flags flags, 140 const cl_image_format *format, 141 size_t width, size_t height, size_t depth, size_t array_size, 142 size_t row_pitch, size_t slice_pitch, size_t size, 143 void *host_ptr, cl_mem buffer); 144 145 public: 146 cl_image_format format() const; 147 virtual cl_uint dimensions() const = 0; 148 size_t width() const; 149 size_t height() const; 150 size_t depth() const; 151 size_t pixel_size() const; 152 size_t row_pitch() const; 153 size_t slice_pitch() const; 154 size_t array_size() const; 155 cl_mem buffer() const; 156 virtual clover::resource & 157 resource_in(command_queue &q); 158 virtual clover::resource & 159 resource_undef(command_queue &q); 160 virtual void 161 resource_out(command_queue &q); 162 163 private: 164 clover::resource & 165 resource(command_queue &q, const void *data_ptr); 166 167 cl_image_format _format; 168 size_t _width; 169 size_t _height; 170 size_t _depth; 171 size_t _row_pitch; 172 size_t _slice_pitch; 173 size_t _array_size; 174 cl_mem _buffer; 175 std::map<device *, 176 std::unique_ptr<root_resource>> resources; 177 std::mutex resources_mtx; 178 }; 179 180 template<cl_mem_object_type Type, cl_uint Dim> 181 class basic_image : public image { 182 public: 183 using image::image; type() const184 virtual cl_mem_object_type type() const { 185 return Type; 186 } dimensions() const187 virtual cl_uint dimensions() const { 188 return Dim; 189 } 190 }; 191 192 class image1d : public basic_image<CL_MEM_OBJECT_IMAGE1D, 1> { 193 public: 194 image1d(clover::context &ctx, 195 std::vector<cl_mem_properties> properties, 196 cl_mem_flags flags, 197 const cl_image_format *format, 198 size_t width, size_t row_pitch, 199 void *host_ptr); 200 }; 201 202 class image1d_buffer : public basic_image<CL_MEM_OBJECT_IMAGE1D_BUFFER, 1> { 203 public: 204 image1d_buffer(clover::context &ctx, 205 std::vector<cl_mem_properties> properties, 206 cl_mem_flags flags, 207 const cl_image_format *format, 208 size_t width, size_t row_pitch, 209 void *host_ptr, cl_mem buffer); 210 }; 211 212 class image1d_array : public basic_image<CL_MEM_OBJECT_IMAGE1D_ARRAY, 1> { 213 public: 214 image1d_array(clover::context &ctx, 215 std::vector<cl_mem_properties> properties, 216 cl_mem_flags flags, 217 const cl_image_format *format, 218 size_t width, 219 size_t array_size, size_t slice_pitch, 220 void *host_ptr); 221 }; 222 223 class image2d : public basic_image<CL_MEM_OBJECT_IMAGE2D, 2> { 224 public: 225 image2d(clover::context &ctx, 226 std::vector<cl_mem_properties> properties, 227 cl_mem_flags flags, 228 const cl_image_format *format, size_t width, 229 size_t height, size_t row_pitch, 230 void *host_ptr); 231 }; 232 233 class image2d_array : public basic_image<CL_MEM_OBJECT_IMAGE2D_ARRAY, 2> { 234 public: 235 image2d_array(clover::context &ctx, 236 std::vector<cl_mem_properties> properties, 237 cl_mem_flags flags, 238 const cl_image_format *format, 239 size_t width, size_t height, size_t array_size, 240 size_t row_pitch, size_t slice_pitch, 241 void *host_ptr); 242 }; 243 244 class image3d : public basic_image<CL_MEM_OBJECT_IMAGE3D, 3>{ 245 public: 246 image3d(clover::context &ctx, 247 std::vector<cl_mem_properties> properties, 248 cl_mem_flags flags, 249 const cl_image_format *format, 250 size_t width, size_t height, size_t depth, 251 size_t row_pitch, size_t slice_pitch, 252 void *host_ptr); 253 }; 254 } 255 256 #endif 257