1db3f68d371c4fbecc4af7c3fe6dc410cdb768bc
[mesa.git] / src / gallium / state_trackers / clover / core / memory.cpp
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 #include "core/memory.hpp"
24 #include "core/resource.hpp"
25 #include "util/u_format.h"
26
27 using namespace clover;
28
29 memory_obj::memory_obj(context &ctx, cl_mem_flags flags,
30 size_t size, void *host_ptr) :
31 ctx(ctx), _flags(flags),
32 _size(size), _host_ptr(host_ptr),
33 _destroy_notify([]{}) {
34 if (flags & (CL_MEM_COPY_HOST_PTR | CL_MEM_USE_HOST_PTR))
35 data.append((char *)host_ptr, size);
36 }
37
38 memory_obj::~memory_obj() {
39 _destroy_notify();
40 }
41
42 bool
43 memory_obj::operator==(const memory_obj &obj) const {
44 return this == &obj;
45 }
46
47 void
48 memory_obj::destroy_notify(std::function<void ()> f) {
49 _destroy_notify = f;
50 }
51
52 cl_mem_flags
53 memory_obj::flags() const {
54 return _flags;
55 }
56
57 size_t
58 memory_obj::size() const {
59 return _size;
60 }
61
62 void *
63 memory_obj::host_ptr() const {
64 return _host_ptr;
65 }
66
67 buffer::buffer(context &ctx, cl_mem_flags flags,
68 size_t size, void *host_ptr) :
69 memory_obj(ctx, flags, size, host_ptr) {
70 }
71
72 cl_mem_object_type
73 buffer::type() const {
74 return CL_MEM_OBJECT_BUFFER;
75 }
76
77 root_buffer::root_buffer(context &ctx, cl_mem_flags flags,
78 size_t size, void *host_ptr) :
79 buffer(ctx, flags, size, host_ptr) {
80 }
81
82 resource &
83 root_buffer::resource(command_queue &q) {
84 // Create a new resource if there's none for this device yet.
85 if (!resources.count(&q.dev)) {
86 auto r = (!resources.empty() ?
87 new root_resource(q.dev, *this, *resources.begin()->second) :
88 new root_resource(q.dev, *this, q, data));
89
90 resources.insert(std::make_pair(&q.dev,
91 std::unique_ptr<root_resource>(r)));
92 data.clear();
93 }
94
95 return *resources.find(&q.dev)->second;
96 }
97
98 sub_buffer::sub_buffer(root_buffer &parent, cl_mem_flags flags,
99 size_t offset, size_t size) :
100 buffer(parent.ctx, flags, size,
101 (char *)parent.host_ptr() + offset),
102 parent(parent), _offset(offset) {
103 }
104
105 resource &
106 sub_buffer::resource(command_queue &q) {
107 // Create a new resource if there's none for this device yet.
108 if (!resources.count(&q.dev)) {
109 auto r = new sub_resource(parent.resource(q), {{ offset() }});
110
111 resources.insert(std::make_pair(&q.dev,
112 std::unique_ptr<sub_resource>(r)));
113 }
114
115 return *resources.find(&q.dev)->second;
116 }
117
118 size_t
119 sub_buffer::offset() const {
120 return _offset;
121 }
122
123 image::image(context &ctx, cl_mem_flags flags,
124 const cl_image_format *format,
125 size_t width, size_t height, size_t depth,
126 size_t row_pitch, size_t slice_pitch, size_t size,
127 void *host_ptr) :
128 memory_obj(ctx, flags, size, host_ptr),
129 _format(*format), _width(width), _height(height), _depth(depth),
130 _row_pitch(row_pitch), _slice_pitch(slice_pitch) {
131 }
132
133 resource &
134 image::resource(command_queue &q) {
135 // Create a new resource if there's none for this device yet.
136 if (!resources.count(&q.dev)) {
137 auto r = (!resources.empty() ?
138 new root_resource(q.dev, *this, *resources.begin()->second) :
139 new root_resource(q.dev, *this, q, data));
140
141 resources.insert(std::make_pair(&q.dev,
142 std::unique_ptr<root_resource>(r)));
143 data.clear();
144 }
145
146 return *resources.find(&q.dev)->second;
147 }
148
149 cl_image_format
150 image::format() const {
151 return _format;
152 }
153
154 size_t
155 image::width() const {
156 return _width;
157 }
158
159 size_t
160 image::height() const {
161 return _height;
162 }
163
164 size_t
165 image::depth() const {
166 return _depth;
167 }
168
169 size_t
170 image::pixel_size() const {
171 return util_format_get_blocksize(translate_format(_format));
172 }
173
174 size_t
175 image::row_pitch() const {
176 return _row_pitch;
177 }
178
179 size_t
180 image::slice_pitch() const {
181 return _slice_pitch;
182 }
183
184 image2d::image2d(context &ctx, cl_mem_flags flags,
185 const cl_image_format *format, size_t width,
186 size_t height, size_t row_pitch,
187 void *host_ptr) :
188 image(ctx, flags, format, width, height, 0,
189 row_pitch, 0, height * row_pitch, host_ptr) {
190 }
191
192 cl_mem_object_type
193 image2d::type() const {
194 return CL_MEM_OBJECT_IMAGE2D;
195 }
196
197 image3d::image3d(context &ctx, cl_mem_flags flags,
198 const cl_image_format *format,
199 size_t width, size_t height, size_t depth,
200 size_t row_pitch, size_t slice_pitch,
201 void *host_ptr) :
202 image(ctx, flags, format, width, height, depth,
203 row_pitch, slice_pitch, depth * slice_pitch,
204 host_ptr) {
205 }
206
207 cl_mem_object_type
208 image3d::type() const {
209 return CL_MEM_OBJECT_IMAGE3D;
210 }