memory.cpp revision c6db1b3396384186aab5b685fe1fd540e17b3a62
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   data((char *)host_ptr, (host_ptr ? size : 0)) {
34}
35
36_cl_mem::~_cl_mem() {
37   __destroy_notify();
38}
39
40void
41_cl_mem::destroy_notify(std::function<void ()> f) {
42   __destroy_notify = f;
43}
44
45cl_mem_flags
46_cl_mem::flags() const {
47   return __flags;
48}
49
50size_t
51_cl_mem::size() const {
52   return __size;
53}
54
55void *
56_cl_mem::host_ptr() const {
57   return __host_ptr;
58}
59
60buffer::buffer(clover::context &ctx, cl_mem_flags flags,
61               size_t size, void *host_ptr) :
62   memory_obj(ctx, flags, size, host_ptr) {
63}
64
65cl_mem_object_type
66buffer::type() const {
67   return CL_MEM_OBJECT_BUFFER;
68}
69
70root_buffer::root_buffer(clover::context &ctx, cl_mem_flags flags,
71                         size_t size, void *host_ptr) :
72   buffer(ctx, flags, size, host_ptr) {
73}
74
75clover::resource &
76root_buffer::resource(cl_command_queue q) {
77   // Create a new resource if there's none for this device yet.
78   if (!resources.count(&q->dev)) {
79      auto r = (!resources.empty() ?
80                new root_resource(q->dev, *this, *resources.begin()->second) :
81                new root_resource(q->dev, *this, data));
82
83      resources.insert(std::make_pair(&q->dev,
84                                      std::unique_ptr<root_resource>(r)));
85      data.clear();
86   }
87
88   return *resources.find(&q->dev)->second;
89}
90
91sub_buffer::sub_buffer(clover::root_buffer &parent, cl_mem_flags flags,
92                       size_t offset, size_t size) :
93   buffer(parent.ctx, flags, size,
94          (char *)parent.host_ptr() + offset),
95   parent(parent), __offset(offset) {
96}
97
98clover::resource &
99sub_buffer::resource(cl_command_queue q) {
100   // Create a new resource if there's none for this device yet.
101   if (!resources.count(&q->dev)) {
102      auto r = new sub_resource(parent.resource(q), { offset() });
103
104      resources.insert(std::make_pair(&q->dev,
105                                      std::unique_ptr<sub_resource>(r)));
106   }
107
108   return *resources.find(&q->dev)->second;
109}
110
111size_t
112sub_buffer::offset() const {
113   return __offset;
114}
115
116image::image(clover::context &ctx, cl_mem_flags flags,
117             const cl_image_format *format,
118             size_t width, size_t height, size_t depth,
119             size_t row_pitch, size_t slice_pitch, size_t size,
120             void *host_ptr) :
121   memory_obj(ctx, flags, size, host_ptr),
122   __format(*format), __width(width), __height(height), __depth(depth),
123   __row_pitch(row_pitch), __slice_pitch(slice_pitch) {
124}
125
126clover::resource &
127image::resource(cl_command_queue q) {
128   // Create a new resource if there's none for this device yet.
129   if (!resources.count(&q->dev)) {
130      auto r = (!resources.empty() ?
131                new root_resource(q->dev, *this, *resources.begin()->second) :
132                new root_resource(q->dev, *this, data));
133
134      resources.insert(std::make_pair(&q->dev,
135                                      std::unique_ptr<root_resource>(r)));
136      data.clear();
137   }
138
139   return *resources.find(&q->dev)->second;
140}
141
142cl_image_format
143image::format() const {
144   return __format;
145}
146
147size_t
148image::width() const {
149   return __width;
150}
151
152size_t
153image::height() const {
154   return __height;
155}
156
157size_t
158image::depth() const {
159   return __depth;
160}
161
162size_t
163image::row_pitch() const {
164   return __row_pitch;
165}
166
167size_t
168image::slice_pitch() const {
169   return __slice_pitch;
170}
171
172image2d::image2d(clover::context &ctx, cl_mem_flags flags,
173                 const cl_image_format *format, size_t width,
174                 size_t height, size_t row_pitch,
175                 void *host_ptr) :
176   image(ctx, flags, format, width, height, 0,
177         row_pitch, 0, height * row_pitch, host_ptr) {
178}
179
180cl_mem_object_type
181image2d::type() const {
182   return CL_MEM_OBJECT_IMAGE2D;
183}
184
185image3d::image3d(clover::context &ctx, cl_mem_flags flags,
186                 const cl_image_format *format,
187                 size_t width, size_t height, size_t depth,
188                 size_t row_pitch, size_t slice_pitch,
189                 void *host_ptr) :
190   image(ctx, flags, format, width, height, depth,
191         row_pitch, slice_pitch, depth * slice_pitch,
192         host_ptr) {
193}
194
195cl_mem_object_type
196image3d::type() const {
197   return CL_MEM_OBJECT_IMAGE3D;
198}
199