1 //---------------------------------------------------------------------------//
2 // Copyright (c) 2013-2015 Kyle Lutz <kyle.r.lutz@gmail.com>
3 //
4 // Distributed under the Boost Software License, Version 1.0
5 // See accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt
7 //
8 // See http://boostorg.github.com/compute for more information.
9 //---------------------------------------------------------------------------//
10 
11 #ifndef BOOST_COMPUTE_IMAGE_IMAGE3D_HPP
12 #define BOOST_COMPUTE_IMAGE_IMAGE3D_HPP
13 
14 #include <boost/throw_exception.hpp>
15 
16 #include <boost/compute/detail/get_object_info.hpp>
17 #include <boost/compute/exception/opencl_error.hpp>
18 #include <boost/compute/image/image_format.hpp>
19 #include <boost/compute/image/image_object.hpp>
20 #include <boost/compute/type_traits/type_name.hpp>
21 #include <boost/compute/utility/extents.hpp>
22 
23 namespace boost {
24 namespace compute {
25 
26 // forward declarations
27 class command_queue;
28 
29 /// \class image3d
30 /// \brief An OpenCL 3D image object
31 ///
32 /// \see image_format, image2d
33 class image3d : public image_object
34 {
35 public:
36     /// Creates a null image3d object.
image3d()37     image3d()
38         : image_object()
39     {
40     }
41 
42     /// Creates a new image3d object.
43     ///
44     /// \see_opencl_ref{clCreateImage}
image3d(const context & context,size_t image_width,size_t image_height,size_t image_depth,const image_format & format,cl_mem_flags flags=read_write,void * host_ptr=0,size_t image_row_pitch=0,size_t image_slice_pitch=0)45     image3d(const context &context,
46             size_t image_width,
47             size_t image_height,
48             size_t image_depth,
49             const image_format &format,
50             cl_mem_flags flags = read_write,
51             void *host_ptr = 0,
52             size_t image_row_pitch = 0,
53             size_t image_slice_pitch = 0)
54     {
55         cl_int error = 0;
56 
57         #ifdef BOOST_COMPUTE_CL_VERSION_1_2
58         cl_image_desc desc;
59         desc.image_type = CL_MEM_OBJECT_IMAGE3D;
60         desc.image_width = image_width;
61         desc.image_height = image_height;
62         desc.image_depth = image_depth;
63         desc.image_array_size = 0;
64         desc.image_row_pitch = image_row_pitch;
65         desc.image_slice_pitch = image_slice_pitch;
66         desc.num_mip_levels = 0;
67         desc.num_samples = 0;
68         #ifdef BOOST_COMPUTE_CL_VERSION_2_0
69         desc.mem_object = 0;
70         #else
71         desc.buffer = 0;
72         #endif
73 
74         m_mem = clCreateImage(context,
75                               flags,
76                               format.get_format_ptr(),
77                               &desc,
78                               host_ptr,
79                               &error);
80         #else
81         m_mem = clCreateImage3D(context,
82                                 flags,
83                                 format.get_format_ptr(),
84                                 image_width,
85                                 image_height,
86                                 image_depth,
87                                 image_row_pitch,
88                                 image_slice_pitch,
89                                 host_ptr,
90                                 &error);
91         #endif
92 
93         if(!m_mem){
94             BOOST_THROW_EXCEPTION(opencl_error(error));
95         }
96     }
97 
98     /// \internal_ (deprecated)
image3d(const context & context,cl_mem_flags flags,const image_format & format,size_t image_width,size_t image_height,size_t image_depth,size_t image_row_pitch,size_t image_slice_pitch=0,void * host_ptr=0)99     image3d(const context &context,
100             cl_mem_flags flags,
101             const image_format &format,
102             size_t image_width,
103             size_t image_height,
104             size_t image_depth,
105             size_t image_row_pitch,
106             size_t image_slice_pitch = 0,
107             void *host_ptr = 0)
108     {
109         cl_int error = 0;
110 
111         #ifdef BOOST_COMPUTE_CL_VERSION_1_2
112         cl_image_desc desc;
113         desc.image_type = CL_MEM_OBJECT_IMAGE3D;
114         desc.image_width = image_width;
115         desc.image_height = image_height;
116         desc.image_depth = image_depth;
117         desc.image_array_size = 0;
118         desc.image_row_pitch = image_row_pitch;
119         desc.image_slice_pitch = image_slice_pitch;
120         desc.num_mip_levels = 0;
121         desc.num_samples = 0;
122         #ifdef BOOST_COMPUTE_CL_VERSION_2_0
123         desc.mem_object = 0;
124         #else
125         desc.buffer = 0;
126         #endif
127 
128         m_mem = clCreateImage(context,
129                               flags,
130                               format.get_format_ptr(),
131                               &desc,
132                               host_ptr,
133                               &error);
134         #else
135         m_mem = clCreateImage3D(context,
136                                 flags,
137                                 format.get_format_ptr(),
138                                 image_width,
139                                 image_height,
140                                 image_depth,
141                                 image_row_pitch,
142                                 image_slice_pitch,
143                                 host_ptr,
144                                 &error);
145         #endif
146 
147         if(!m_mem){
148             BOOST_THROW_EXCEPTION(opencl_error(error));
149         }
150     }
151 
152     /// Creates a new image3d as a copy of \p other.
image3d(const image3d & other)153     image3d(const image3d &other)
154         : image_object(other)
155     {
156     }
157 
158     /// Copies the image3d from \p other.
operator =(const image3d & other)159     image3d& operator=(const image3d &other)
160     {
161         image_object::operator=(other);
162 
163         return *this;
164     }
165 
166     #ifndef BOOST_COMPUTE_NO_RVALUE_REFERENCES
167     /// Move-constructs a new image object from \p other.
image3d(image3d && other)168     image3d(image3d&& other) BOOST_NOEXCEPT
169         : image_object(std::move(other))
170     {
171     }
172 
173     /// Move-assigns the image from \p other to \c *this.
operator =(image3d && other)174     image3d& operator=(image3d&& other) BOOST_NOEXCEPT
175     {
176         image_object::operator=(std::move(other));
177 
178         return *this;
179     }
180     #endif // BOOST_COMPUTE_NO_RVALUE_REFERENCES
181 
182     /// Destroys the image3d object.
~image3d()183     ~image3d()
184     {
185     }
186 
187     /// Returns the size (width, height, depth) of the image.
size() const188     extents<3> size() const
189     {
190         extents<3> size;
191         size[0] = get_info<size_t>(CL_IMAGE_WIDTH);
192         size[1] = get_info<size_t>(CL_IMAGE_HEIGHT);
193         size[2] = get_info<size_t>(CL_IMAGE_DEPTH);
194         return size;
195     }
196 
197     /// Returns the origin of the image (\c 0, \c 0, \c 0).
origin() const198     extents<3> origin() const
199     {
200         return extents<3>();
201     }
202 
203     /// Returns information about the image.
204     ///
205     /// \see_opencl_ref{clGetImageInfo}
206     template<class T>
get_info(cl_image_info info) const207     T get_info(cl_image_info info) const
208     {
209         return detail::get_object_info<T>(clGetImageInfo, m_mem, info);
210     }
211 
212     /// \overload
213     template<int Enum>
214     typename detail::get_object_info_type<image3d, Enum>::type
215     get_info() const;
216 
217     /// Returns the supported 3D image formats for the context.
218     ///
219     /// \see_opencl_ref{clGetSupportedImageFormats}
220     static std::vector<image_format>
get_supported_formats(const context & context,cl_mem_flags flags=read_write)221     get_supported_formats(const context &context, cl_mem_flags flags = read_write)
222     {
223         return image_object::get_supported_formats(context, CL_MEM_OBJECT_IMAGE3D, flags);
224     }
225 
226     /// Returns \c true if \p format is a supported 3D image format for
227     /// \p context.
is_supported_format(const image_format & format,const context & context,cl_mem_flags flags=read_write)228     static bool is_supported_format(const image_format &format,
229                                     const context &context,
230                                     cl_mem_flags flags = read_write)
231     {
232         return image_object::is_supported_format(
233             format, context, CL_MEM_OBJECT_IMAGE3D, flags
234         );
235     }
236 
237     /// Creates a new image with a copy of the data in \c *this. Uses \p queue
238     /// to perform the copy operation.
239     image3d clone(command_queue &queue) const;
240 };
241 
242 /// \internal_ define get_info() specializations for image3d
243 BOOST_COMPUTE_DETAIL_DEFINE_GET_INFO_SPECIALIZATIONS(image3d,
244     ((cl_image_format, CL_IMAGE_FORMAT))
245     ((size_t, CL_IMAGE_ELEMENT_SIZE))
246     ((size_t, CL_IMAGE_ROW_PITCH))
247     ((size_t, CL_IMAGE_SLICE_PITCH))
248     ((size_t, CL_IMAGE_WIDTH))
249     ((size_t, CL_IMAGE_HEIGHT))
250     ((size_t, CL_IMAGE_DEPTH))
251 )
252 
253 namespace detail {
254 
255 // set_kernel_arg() specialization for image3d
256 template<>
257 struct set_kernel_arg<image3d> : public set_kernel_arg<image_object> { };
258 
259 } // end detail namespace
260 } // end compute namespace
261 } // end boost namespace
262 
263 BOOST_COMPUTE_TYPE_NAME(boost::compute::image3d, image3d_t)
264 
265 #endif // BOOST_COMPUTE_IMAGE_IMAGE3D_HPP
266