File indexing completed on 2025-11-03 09:17:45
0001 
0002 
0003 
0004 
0005 
0006 
0007 
0008 
0009 
0010 
0011 #ifndef BOOST_COMPUTE_IMAGE_IMAGE_SAMPLER_HPP
0012 #define BOOST_COMPUTE_IMAGE_IMAGE_SAMPLER_HPP
0013 
0014 #include <boost/throw_exception.hpp>
0015 
0016 #include <boost/compute/config.hpp>
0017 #include <boost/compute/context.hpp>
0018 #include <boost/compute/kernel.hpp>
0019 #include <boost/compute/detail/get_object_info.hpp>
0020 #include <boost/compute/detail/assert_cl_success.hpp>
0021 #include <boost/compute/exception/opencl_error.hpp>
0022 #include <boost/compute/type_traits/type_name.hpp>
0023 
0024 namespace boost {
0025 namespace compute {
0026 
0027 
0028 
0029 
0030 
0031 class image_sampler
0032 {
0033 public:
0034     enum addressing_mode {
0035         none = CL_ADDRESS_NONE,
0036         clamp_to_edge = CL_ADDRESS_CLAMP_TO_EDGE,
0037         clamp = CL_ADDRESS_CLAMP,
0038         repeat = CL_ADDRESS_REPEAT
0039     };
0040 
0041     enum filter_mode {
0042         nearest = CL_FILTER_NEAREST,
0043         linear = CL_FILTER_LINEAR
0044     };
0045 
0046     image_sampler()
0047         : m_sampler(0)
0048     {
0049     }
0050 
0051     image_sampler(const context &context,
0052                   bool normalized_coords,
0053                   cl_addressing_mode addressing_mode,
0054                   cl_filter_mode filter_mode)
0055     {
0056         cl_int error = 0;
0057 
0058         #ifdef BOOST_COMPUTE_CL_VERSION_2_0
0059         std::vector<cl_sampler_properties> sampler_properties;
0060         sampler_properties.push_back(CL_SAMPLER_NORMALIZED_COORDS);
0061         sampler_properties.push_back(cl_sampler_properties(normalized_coords));
0062         sampler_properties.push_back(CL_SAMPLER_ADDRESSING_MODE);
0063         sampler_properties.push_back(cl_sampler_properties(addressing_mode));
0064         sampler_properties.push_back(CL_SAMPLER_FILTER_MODE);
0065         sampler_properties.push_back(cl_sampler_properties(filter_mode));
0066         sampler_properties.push_back(cl_sampler_properties(0));
0067 
0068         m_sampler = clCreateSamplerWithProperties(
0069             context, &sampler_properties[0], &error
0070         );
0071         #else
0072         m_sampler = clCreateSampler(
0073             context, normalized_coords, addressing_mode, filter_mode, &error
0074         );
0075         #endif
0076 
0077         if(!m_sampler){
0078             BOOST_THROW_EXCEPTION(opencl_error(error));
0079         }
0080     }
0081 
0082     explicit image_sampler(cl_sampler sampler, bool retain = true)
0083         : m_sampler(sampler)
0084     {
0085         if(m_sampler && retain){
0086             clRetainSampler(m_sampler);
0087         }
0088     }
0089 
0090     
0091     image_sampler(const image_sampler &other)
0092         : m_sampler(other.m_sampler)
0093     {
0094         if(m_sampler){
0095             clRetainSampler(m_sampler);
0096         }
0097     }
0098 
0099     
0100     image_sampler& operator=(const image_sampler &other)
0101     {
0102         if(this != &other){
0103             if(m_sampler){
0104                 clReleaseSampler(m_sampler);
0105             }
0106 
0107             m_sampler = other.m_sampler;
0108 
0109             if(m_sampler){
0110                 clRetainSampler(m_sampler);
0111             }
0112         }
0113 
0114         return *this;
0115     }
0116 
0117     #ifndef BOOST_COMPUTE_NO_RVALUE_REFERENCES
0118     image_sampler(image_sampler&& other) BOOST_NOEXCEPT
0119         : m_sampler(other.m_sampler)
0120     {
0121         other.m_sampler = 0;
0122     }
0123 
0124     image_sampler& operator=(image_sampler&& other) BOOST_NOEXCEPT
0125     {
0126         if(m_sampler){
0127             clReleaseSampler(m_sampler);
0128         }
0129 
0130         m_sampler = other.m_sampler;
0131         other.m_sampler = 0;
0132 
0133         return *this;
0134     }
0135     #endif 
0136 
0137     
0138     ~image_sampler()
0139     {
0140         if(m_sampler){
0141             BOOST_COMPUTE_ASSERT_CL_SUCCESS(
0142                 clReleaseSampler(m_sampler)
0143             );
0144         }
0145     }
0146 
0147     
0148     cl_sampler& get() const
0149     {
0150         return const_cast<cl_sampler &>(m_sampler);
0151     }
0152 
0153     
0154     context get_context() const
0155     {
0156         return context(get_info<cl_context>(CL_SAMPLER_CONTEXT));
0157     }
0158 
0159     
0160     
0161     
0162     template<class T>
0163     T get_info(cl_sampler_info info) const
0164     {
0165         return detail::get_object_info<T>(clGetSamplerInfo, m_sampler, info);
0166     }
0167 
0168     
0169     template<int Enum>
0170     typename detail::get_object_info_type<image_sampler, Enum>::type
0171     get_info() const;
0172 
0173     
0174     bool operator==(const image_sampler &other) const
0175     {
0176         return m_sampler == other.m_sampler;
0177     }
0178 
0179     
0180     bool operator!=(const image_sampler &other) const
0181     {
0182         return m_sampler != other.m_sampler;
0183     }
0184 
0185     operator cl_sampler() const
0186     {
0187         return m_sampler;
0188     }
0189 
0190 private:
0191     cl_sampler m_sampler;
0192 };
0193 
0194 
0195 BOOST_COMPUTE_DETAIL_DEFINE_GET_INFO_SPECIALIZATIONS(image_sampler,
0196     ((cl_uint, CL_SAMPLER_REFERENCE_COUNT))
0197     ((cl_context, CL_SAMPLER_CONTEXT))
0198     ((cl_addressing_mode, CL_SAMPLER_ADDRESSING_MODE))
0199     ((cl_filter_mode, CL_SAMPLER_FILTER_MODE))
0200     ((bool, CL_SAMPLER_NORMALIZED_COORDS))
0201 )
0202 
0203 namespace detail {
0204 
0205 
0206 template<>
0207 struct set_kernel_arg<image_sampler>
0208 {
0209     void operator()(kernel &kernel_, size_t index, const image_sampler &sampler)
0210     {
0211         kernel_.set_arg(index, sampler.get());
0212     }
0213 };
0214 
0215 } 
0216 } 
0217 } 
0218 
0219 BOOST_COMPUTE_TYPE_NAME(boost::compute::image_sampler, sampler_t)
0220 
0221 #endif