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,
142             size_t row_pitch, size_t slice_pitch, size_t size,
143             void *host_ptr);
144 
145    public:
146       cl_image_format format() const;
147       size_t width() const;
148       size_t height() const;
149       size_t depth() const;
150       size_t pixel_size() const;
151       size_t row_pitch() const;
152       size_t slice_pitch() const;
153       virtual clover::resource &
154       resource_in(command_queue &q);
155       virtual clover::resource &
156       resource_undef(command_queue &q);
157       virtual void
158       resource_out(command_queue &q);
159 
160    private:
161       clover::resource &
162          resource(command_queue &q, const void *data_ptr);
163 
164       cl_image_format _format;
165       size_t _width;
166       size_t _height;
167       size_t _depth;
168       size_t _row_pitch;
169       size_t _slice_pitch;
170       std::map<device *,
171                std::unique_ptr<root_resource>> resources;
172       std::mutex resources_mtx;
173    };
174 
175    class image1d : public image {
176    public:
177       image1d(clover::context &ctx,
178               std::vector<cl_mem_properties> properties,
179               cl_mem_flags flags,
180               const cl_image_format *format,
181               size_t width, size_t row_pitch,
182               void *host_ptr);
183 
184       virtual cl_mem_object_type type() const;
185    };
186 
187    class image2d : public image {
188    public:
189       image2d(clover::context &ctx,
190               std::vector<cl_mem_properties> properties,
191               cl_mem_flags flags,
192               const cl_image_format *format, size_t width,
193               size_t height, size_t row_pitch,
194               void *host_ptr);
195 
196       virtual cl_mem_object_type type() const;
197    };
198 
199    class image3d : public image {
200    public:
201       image3d(clover::context &ctx,
202               std::vector<cl_mem_properties> properties,
203               cl_mem_flags flags,
204               const cl_image_format *format,
205               size_t width, size_t height, size_t depth,
206               size_t row_pitch, size_t slice_pitch,
207               void *host_ptr);
208 
209       virtual cl_mem_object_type type() const;
210    };
211 }
212 
213 #endif
214