From ff6e119572158beaf852c4eb8f8cbfcfaab99cc1 Mon Sep 17 00:00:00 2001 From: Andreas Kloeckner <inform@tiker.net> Date: Mon, 13 Aug 2018 15:28:01 -0500 Subject: [PATCH] Implement sampler creation with properties --- doc/runtime_memory.rst | 27 +++++++++++---- src/wrap_cl.hpp | 76 ++++++++++++++++++++++++++++++++++++++---- src/wrap_cl_part_2.cpp | 3 ++ 3 files changed, 93 insertions(+), 13 deletions(-) diff --git a/doc/runtime_memory.rst b/doc/runtime_memory.rst index 8431e44a..a4ad2d5f 100644 --- a/doc/runtime_memory.rst +++ b/doc/runtime_memory.rst @@ -352,13 +352,28 @@ Mapping Memory into Host Address Space Samplers -------- -.. class:: Sampler(context, normalized_coords, addressing_mode, filter_mode) +.. class:: Sampler - *normalized_coords* is a :class:`bool` indicating whether - to use coordinates between 0 and 1 (*True*) or the texture's - natural pixel size (*False*). - See :class:`addressing_mode` and :class:`filter_mode` for possible - argument values. + + .. method:: __init__(context, normalized_coords, addressing_mode, filter_mode) + + *normalized_coords* is a :class:`bool` indicating whether + to use coordinates between 0 and 1 (*True*) or the texture's + natural pixel size (*False*). + See :class:`addressing_mode` and :class:`filter_mode` for possible + argument values. + + .. method:: __init__(context, properties) + + :arg properties: a sequence + of keys and values from :class:`sampler_properties` as accepted + by :c:func:`clCreateSamplerWithProperties` (see the OpenCL + spec for details). The trailing *0* is added automatically + and does not need to be included. + + Requires OpenCL 2 or newer. + + .. versionadded:: 2018.2 .. attribute:: info diff --git a/src/wrap_cl.hpp b/src/wrap_cl.hpp index a444b798..a55c1806 100644 --- a/src/wrap_cl.hpp +++ b/src/wrap_cl.hpp @@ -3523,26 +3523,88 @@ namespace pyopencl cl_sampler m_sampler; public: +#if PYOPENCL_CL_VERSION >= 0x2000 + sampler(context const &ctx, py::sequence py_props) + { + int hex_plat_version = ctx.get_hex_platform_version(); + + if (hex_plat_version < 0x2000) + { + std::cerr << + "sampler properties given as an iterable, " + "which uses an OpenCL 2+-only interface, " + "but the context's platform does not " + "declare OpenCL 2 support. Proceeding " + "as requested, but the next thing you see " + "may be a crash." << std:: endl; + } + + cl_sampler_properties props[py::len(py_props) + 1]; + { + size_t i = 0; + for (auto prop: py_props) + props[i++] = py::cast<cl_sampler_properties>(prop); + props[i++] = 0; + } + + cl_int status_code; + PYOPENCL_PRINT_CALL_TRACE("clCreateSamplerWithProperties"); + + m_sampler = clCreateSamplerWithProperties( + ctx.data(), + props, + &status_code); + + if (status_code != CL_SUCCESS) + throw pyopencl::error("Sampler", status_code); + } +#endif + sampler(context const &ctx, bool normalized_coordinates, cl_addressing_mode am, cl_filter_mode fm) { - cl_int status_code; PYOPENCL_PRINT_CALL_TRACE("clCreateSampler"); + int hex_plat_version = ctx.get_hex_platform_version(); +#if PYOPENCL_CL_VERSION >= 0x2000 + if (hex_plat_version >= 0x2000) + { + cl_sampler_properties props_list[] = { + CL_SAMPLER_NORMALIZED_COORDS, normalized_coordinates, + CL_SAMPLER_ADDRESSING_MODE, am, + CL_SAMPLER_FILTER_MODE, fm, + 0, + }; + + cl_int status_code; + + PYOPENCL_PRINT_CALL_TRACE("clCreateSamplerWithProperties"); + m_sampler = clCreateSamplerWithProperties( + ctx.data(), props_list, &status_code); + + if (status_code != CL_SUCCESS) + throw pyopencl::error("Sampler", status_code); + } + else +#endif + { + cl_int status_code; + #if defined(__GNUG__) && !defined(__clang__) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" #endif - m_sampler = clCreateSampler( - ctx.data(), - normalized_coordinates, - am, fm, &status_code); + m_sampler = clCreateSampler( + ctx.data(), + normalized_coordinates, + am, fm, &status_code); #if defined(__GNUG__) && !defined(__clang__) #pragma GCC diagnostic pop #endif - if (status_code != CL_SUCCESS) - throw pyopencl::error("Sampler", status_code); + if (status_code != CL_SUCCESS) + throw pyopencl::error("Sampler", status_code); + } } sampler(cl_sampler samp, bool retain) diff --git a/src/wrap_cl_part_2.cpp b/src/wrap_cl_part_2.cpp index ac1533e2..2e8e9e4c 100644 --- a/src/wrap_cl_part_2.cpp +++ b/src/wrap_cl_part_2.cpp @@ -299,6 +299,9 @@ void pyopencl_expose_part_2(py::module &m) { typedef sampler cls; py::class_<cls>(m, "Sampler", py::dynamic_attr()) +#if PYOPENCL_CL_VERSION >= 0x2000 + .def(py::init<context const &, py::sequence>()) +#endif .def(py::init<context const &, bool, cl_addressing_mode, cl_filter_mode>()) .DEF_SIMPLE_METHOD(get_info) .def(py::self == py::self) -- GitLab