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_IMAGE_SAMPLER_HPP 12 #define BOOST_COMPUTE_IMAGE_IMAGE_SAMPLER_HPP 13 14 #include <boost/throw_exception.hpp> 15 16 #include <boost/compute/config.hpp> 17 #include <boost/compute/context.hpp> 18 #include <boost/compute/kernel.hpp> 19 #include <boost/compute/detail/get_object_info.hpp> 20 #include <boost/compute/detail/assert_cl_success.hpp> 21 #include <boost/compute/exception/opencl_error.hpp> 22 #include <boost/compute/type_traits/type_name.hpp> 23 24 namespace boost { 25 namespace compute { 26 27 /// \class image_sampler 28 /// \brief An OpenCL image sampler object 29 /// 30 /// \see image2d, image_format 31 class image_sampler 32 { 33 public: 34 enum addressing_mode { 35 none = CL_ADDRESS_NONE, 36 clamp_to_edge = CL_ADDRESS_CLAMP_TO_EDGE, 37 clamp = CL_ADDRESS_CLAMP, 38 repeat = CL_ADDRESS_REPEAT 39 }; 40 41 enum filter_mode { 42 nearest = CL_FILTER_NEAREST, 43 linear = CL_FILTER_LINEAR 44 }; 45 image_sampler()46 image_sampler() 47 : m_sampler(0) 48 { 49 } 50 image_sampler(const context & context,bool normalized_coords,cl_addressing_mode addressing_mode,cl_filter_mode filter_mode)51 image_sampler(const context &context, 52 bool normalized_coords, 53 cl_addressing_mode addressing_mode, 54 cl_filter_mode filter_mode) 55 { 56 cl_int error = 0; 57 58 #ifdef BOOST_COMPUTE_CL_VERSION_2_0 59 std::vector<cl_sampler_properties> sampler_properties; 60 sampler_properties.push_back(CL_SAMPLER_NORMALIZED_COORDS); 61 sampler_properties.push_back(cl_sampler_properties(normalized_coords)); 62 sampler_properties.push_back(CL_SAMPLER_ADDRESSING_MODE); 63 sampler_properties.push_back(cl_sampler_properties(addressing_mode)); 64 sampler_properties.push_back(CL_SAMPLER_FILTER_MODE); 65 sampler_properties.push_back(cl_sampler_properties(filter_mode)); 66 sampler_properties.push_back(cl_sampler_properties(0)); 67 68 m_sampler = clCreateSamplerWithProperties( 69 context, &sampler_properties[0], &error 70 ); 71 #else 72 m_sampler = clCreateSampler( 73 context, normalized_coords, addressing_mode, filter_mode, &error 74 ); 75 #endif 76 77 if(!m_sampler){ 78 BOOST_THROW_EXCEPTION(opencl_error(error)); 79 } 80 } 81 image_sampler(cl_sampler sampler,bool retain=true)82 explicit image_sampler(cl_sampler sampler, bool retain = true) 83 : m_sampler(sampler) 84 { 85 if(m_sampler && retain){ 86 clRetainSampler(m_sampler); 87 } 88 } 89 90 /// Creates a new image sampler object as a copy of \p other. image_sampler(const image_sampler & other)91 image_sampler(const image_sampler &other) 92 : m_sampler(other.m_sampler) 93 { 94 if(m_sampler){ 95 clRetainSampler(m_sampler); 96 } 97 } 98 99 /// Copies the image sampler object from \p other to \c *this. operator =(const image_sampler & other)100 image_sampler& operator=(const image_sampler &other) 101 { 102 if(this != &other){ 103 if(m_sampler){ 104 clReleaseSampler(m_sampler); 105 } 106 107 m_sampler = other.m_sampler; 108 109 if(m_sampler){ 110 clRetainSampler(m_sampler); 111 } 112 } 113 114 return *this; 115 } 116 117 #ifndef BOOST_COMPUTE_NO_RVALUE_REFERENCES image_sampler(image_sampler && other)118 image_sampler(image_sampler&& other) BOOST_NOEXCEPT 119 : m_sampler(other.m_sampler) 120 { 121 other.m_sampler = 0; 122 } 123 operator =(image_sampler && other)124 image_sampler& operator=(image_sampler&& other) BOOST_NOEXCEPT 125 { 126 if(m_sampler){ 127 clReleaseSampler(m_sampler); 128 } 129 130 m_sampler = other.m_sampler; 131 other.m_sampler = 0; 132 133 return *this; 134 } 135 #endif // BOOST_COMPUTE_NO_RVALUE_REFERENCES 136 137 /// Destroys the image sampler object. ~image_sampler()138 ~image_sampler() 139 { 140 if(m_sampler){ 141 BOOST_COMPUTE_ASSERT_CL_SUCCESS( 142 clReleaseSampler(m_sampler) 143 ); 144 } 145 } 146 147 /// Returns the underlying \c cl_sampler object. get() const148 cl_sampler& get() const 149 { 150 return const_cast<cl_sampler &>(m_sampler); 151 } 152 153 /// Returns the context for the image sampler object. get_context() const154 context get_context() const 155 { 156 return context(get_info<cl_context>(CL_SAMPLER_CONTEXT)); 157 } 158 159 /// Returns information about the sampler. 160 /// 161 /// \see_opencl_ref{clGetSamplerInfo} 162 template<class T> get_info(cl_sampler_info info) const163 T get_info(cl_sampler_info info) const 164 { 165 return detail::get_object_info<T>(clGetSamplerInfo, m_sampler, info); 166 } 167 168 /// \overload 169 template<int Enum> 170 typename detail::get_object_info_type<image_sampler, Enum>::type 171 get_info() const; 172 173 /// Returns \c true if the sampler is the same at \p other. operator ==(const image_sampler & other) const174 bool operator==(const image_sampler &other) const 175 { 176 return m_sampler == other.m_sampler; 177 } 178 179 /// Returns \c true if the sampler is different from \p other. operator !=(const image_sampler & other) const180 bool operator!=(const image_sampler &other) const 181 { 182 return m_sampler != other.m_sampler; 183 } 184 operator cl_sampler() const185 operator cl_sampler() const 186 { 187 return m_sampler; 188 } 189 190 private: 191 cl_sampler m_sampler; 192 }; 193 194 /// \internal_ define get_info() specializations for image_sampler 195 BOOST_COMPUTE_DETAIL_DEFINE_GET_INFO_SPECIALIZATIONS(image_sampler, 196 ((cl_uint, CL_SAMPLER_REFERENCE_COUNT)) 197 ((cl_context, CL_SAMPLER_CONTEXT)) 198 ((cl_addressing_mode, CL_SAMPLER_ADDRESSING_MODE)) 199 ((cl_filter_mode, CL_SAMPLER_FILTER_MODE)) 200 ((bool, CL_SAMPLER_NORMALIZED_COORDS)) 201 ) 202 203 namespace detail { 204 205 // set_kernel_arg specialization for image samplers 206 template<> 207 struct set_kernel_arg<image_sampler> 208 { operator ()boost::compute::detail::set_kernel_arg209 void operator()(kernel &kernel_, size_t index, const image_sampler &sampler) 210 { 211 kernel_.set_arg(index, sampler.get()); 212 } 213 }; 214 215 } // end detail namespace 216 } // end compute namespace 217 } // end boost namespace 218 219 BOOST_COMPUTE_TYPE_NAME(boost::compute::image_sampler, sampler_t) 220 221 #endif // BOOST_COMPUTE_IMAGE_IMAGE_SAMPLER_HPP 222