xref: /aosp_15_r20/external/OpenCL-CLHPP/include/CL/opencl.hpp (revision 6fee86a4f833e4f32f25770a262884407554133d)
1*6fee86a4SJeremy Kemp //
2*6fee86a4SJeremy Kemp // Copyright (c) 2008-2023 The Khronos Group Inc.
3*6fee86a4SJeremy Kemp //
4*6fee86a4SJeremy Kemp // Licensed under the Apache License, Version 2.0 (the "License");
5*6fee86a4SJeremy Kemp // you may not use this file except in compliance with the License.
6*6fee86a4SJeremy Kemp // You may obtain a copy of the License at
7*6fee86a4SJeremy Kemp //
8*6fee86a4SJeremy Kemp //    http://www.apache.org/licenses/LICENSE-2.0
9*6fee86a4SJeremy Kemp //
10*6fee86a4SJeremy Kemp // Unless required by applicable law or agreed to in writing, software
11*6fee86a4SJeremy Kemp // distributed under the License is distributed on an "AS IS" BASIS,
12*6fee86a4SJeremy Kemp // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*6fee86a4SJeremy Kemp // See the License for the specific language governing permissions and
14*6fee86a4SJeremy Kemp // limitations under the License.
15*6fee86a4SJeremy Kemp //
16*6fee86a4SJeremy Kemp 
17*6fee86a4SJeremy Kemp /*! \file
18*6fee86a4SJeremy Kemp  *
19*6fee86a4SJeremy Kemp  *   \brief C++ bindings for OpenCL 1.0, OpenCL 1.1, OpenCL 1.2,
20*6fee86a4SJeremy Kemp  *       OpenCL 2.0, OpenCL 2.1, OpenCL 2.2, and OpenCL 3.0.
21*6fee86a4SJeremy Kemp  *   \author Lee Howes and Bruce Merry
22*6fee86a4SJeremy Kemp  *
23*6fee86a4SJeremy Kemp  *   Derived from the OpenCL 1.x C++ bindings written by
24*6fee86a4SJeremy Kemp  *   Benedict R. Gaster, Laurent Morichetti and Lee Howes
25*6fee86a4SJeremy Kemp  *   With additions and fixes from:
26*6fee86a4SJeremy Kemp  *       Brian Cole, March 3rd 2010 and April 2012
27*6fee86a4SJeremy Kemp  *       Matt Gruenke, April 2012.
28*6fee86a4SJeremy Kemp  *       Bruce Merry, February 2013.
29*6fee86a4SJeremy Kemp  *       Tom Deakin and Simon McIntosh-Smith, July 2013
30*6fee86a4SJeremy Kemp  *       James Price, 2015-
31*6fee86a4SJeremy Kemp  *   \version 2.2.0
32*6fee86a4SJeremy Kemp  *   \date 2019-09-18
33*6fee86a4SJeremy Kemp  *
34*6fee86a4SJeremy Kemp  *   Optional extension support
35*6fee86a4SJeremy Kemp  *
36*6fee86a4SJeremy Kemp  *         cl_khr_d3d10_sharing
37*6fee86a4SJeremy Kemp  *         #define CL_HPP_USE_DX_INTEROP
38*6fee86a4SJeremy Kemp  *         cl_khr_il_program
39*6fee86a4SJeremy Kemp  *         #define CL_HPP_USE_IL_KHR
40*6fee86a4SJeremy Kemp  *         cl_khr_sub_groups
41*6fee86a4SJeremy Kemp  *         #define CL_HPP_USE_CL_SUB_GROUPS_KHR
42*6fee86a4SJeremy Kemp  *
43*6fee86a4SJeremy Kemp  *   Doxygen documentation for this header is available here:
44*6fee86a4SJeremy Kemp  *
45*6fee86a4SJeremy Kemp  *       http://khronosgroup.github.io/OpenCL-CLHPP/
46*6fee86a4SJeremy Kemp  *
47*6fee86a4SJeremy Kemp  *   The latest version of this header can be found on the GitHub releases page:
48*6fee86a4SJeremy Kemp  *
49*6fee86a4SJeremy Kemp  *       https://github.com/KhronosGroup/OpenCL-CLHPP/releases
50*6fee86a4SJeremy Kemp  *
51*6fee86a4SJeremy Kemp  *   Bugs and patches can be submitted to the GitHub repository:
52*6fee86a4SJeremy Kemp  *
53*6fee86a4SJeremy Kemp  *       https://github.com/KhronosGroup/OpenCL-CLHPP
54*6fee86a4SJeremy Kemp  */
55*6fee86a4SJeremy Kemp 
56*6fee86a4SJeremy Kemp /*! \mainpage
57*6fee86a4SJeremy Kemp  * \section intro Introduction
58*6fee86a4SJeremy Kemp  * For many large applications C++ is the language of choice and so it seems
59*6fee86a4SJeremy Kemp  * reasonable to define C++ bindings for OpenCL.
60*6fee86a4SJeremy Kemp  *
61*6fee86a4SJeremy Kemp  * The interface is contained with a single C++ header file \em opencl.hpp and all
62*6fee86a4SJeremy Kemp  * definitions are contained within the namespace \em cl. There is no additional
63*6fee86a4SJeremy Kemp  * requirement to include \em cl.h and to use either the C++ or original C
64*6fee86a4SJeremy Kemp  * bindings; it is enough to simply include \em opencl.hpp.
65*6fee86a4SJeremy Kemp  *
66*6fee86a4SJeremy Kemp  * The bindings themselves are lightweight and correspond closely to the
67*6fee86a4SJeremy Kemp  * underlying C API. Using the C++ bindings introduces no additional execution
68*6fee86a4SJeremy Kemp  * overhead.
69*6fee86a4SJeremy Kemp  *
70*6fee86a4SJeremy Kemp  * There are numerous compatibility, portability and memory management
71*6fee86a4SJeremy Kemp  * fixes in the new header as well as additional OpenCL 2.0 features.
72*6fee86a4SJeremy Kemp  * As a result the header is not directly backward compatible and for this
73*6fee86a4SJeremy Kemp  * reason we release it as opencl.hpp rather than a new version of cl.hpp.
74*6fee86a4SJeremy Kemp  *
75*6fee86a4SJeremy Kemp  *
76*6fee86a4SJeremy Kemp  * \section compatibility Compatibility
77*6fee86a4SJeremy Kemp  * Due to the evolution of the underlying OpenCL API the 2.0 C++ bindings
78*6fee86a4SJeremy Kemp  * include an updated approach to defining supported feature versions
79*6fee86a4SJeremy Kemp  * and the range of valid underlying OpenCL runtime versions supported.
80*6fee86a4SJeremy Kemp  *
81*6fee86a4SJeremy Kemp  * The combination of preprocessor macros CL_HPP_TARGET_OPENCL_VERSION and
82*6fee86a4SJeremy Kemp  * CL_HPP_MINIMUM_OPENCL_VERSION control this range. These are three digit
83*6fee86a4SJeremy Kemp  * decimal values representing OpenCL runtime versions. The default for
84*6fee86a4SJeremy Kemp  * the target is 300, representing OpenCL 3.0.  The minimum is defined as 200.
85*6fee86a4SJeremy Kemp  * These settings would use 2.0 and newer API calls only.
86*6fee86a4SJeremy Kemp  * If backward compatibility with a 1.2 runtime is required, the minimum
87*6fee86a4SJeremy Kemp  * version may be set to 120.
88*6fee86a4SJeremy Kemp  *
89*6fee86a4SJeremy Kemp  * Note that this is a compile-time setting, and so affects linking against
90*6fee86a4SJeremy Kemp  * a particular SDK version rather than the versioning of the loaded runtime.
91*6fee86a4SJeremy Kemp  *
92*6fee86a4SJeremy Kemp  * The earlier versions of the header included basic vector and string
93*6fee86a4SJeremy Kemp  * classes based loosely on STL versions. These were difficult to
94*6fee86a4SJeremy Kemp  * maintain and very rarely used. For the 2.0 header we now assume
95*6fee86a4SJeremy Kemp  * the presence of the standard library unless requested otherwise.
96*6fee86a4SJeremy Kemp  * We use std::array, std::vector, std::shared_ptr and std::string
97*6fee86a4SJeremy Kemp  * throughout to safely manage memory and reduce the chance of a
98*6fee86a4SJeremy Kemp  * recurrance of earlier memory management bugs.
99*6fee86a4SJeremy Kemp  *
100*6fee86a4SJeremy Kemp  * These classes are used through typedefs in the cl namespace:
101*6fee86a4SJeremy Kemp  * cl::array, cl::vector, cl::pointer and cl::string.
102*6fee86a4SJeremy Kemp  * In addition cl::allocate_pointer forwards to std::allocate_shared
103*6fee86a4SJeremy Kemp  * by default.
104*6fee86a4SJeremy Kemp  * In all cases these standard library classes can be replaced with
105*6fee86a4SJeremy Kemp  * custom interface-compatible versions using the CL_HPP_NO_STD_ARRAY,
106*6fee86a4SJeremy Kemp  * CL_HPP_NO_STD_VECTOR, CL_HPP_NO_STD_UNIQUE_PTR and
107*6fee86a4SJeremy Kemp  * CL_HPP_NO_STD_STRING macros.
108*6fee86a4SJeremy Kemp  *
109*6fee86a4SJeremy Kemp  * The OpenCL 1.x versions of the C++ bindings included a size_t wrapper
110*6fee86a4SJeremy Kemp  * class to interface with kernel enqueue. This caused unpleasant interactions
111*6fee86a4SJeremy Kemp  * with the standard size_t declaration and led to namespacing bugs.
112*6fee86a4SJeremy Kemp  * In the 2.0 version we have replaced this with a std::array-based interface.
113*6fee86a4SJeremy Kemp  * However, the old behaviour can be regained for backward compatibility
114*6fee86a4SJeremy Kemp  * using the CL_HPP_ENABLE_SIZE_T_COMPATIBILITY macro.
115*6fee86a4SJeremy Kemp  *
116*6fee86a4SJeremy Kemp  * Finally, the program construction interface used a clumsy vector-of-pairs
117*6fee86a4SJeremy Kemp  * design in the earlier versions. We have replaced that with a cleaner
118*6fee86a4SJeremy Kemp  * vector-of-vectors and vector-of-strings design. However, for backward
119*6fee86a4SJeremy Kemp  * compatibility old behaviour can be regained with the
120*6fee86a4SJeremy Kemp  * CL_HPP_ENABLE_PROGRAM_CONSTRUCTION_FROM_ARRAY_COMPATIBILITY macro.
121*6fee86a4SJeremy Kemp  *
122*6fee86a4SJeremy Kemp  * In OpenCL 2.0 OpenCL C is not entirely backward compatibility with
123*6fee86a4SJeremy Kemp  * earlier versions. As a result a flag must be passed to the OpenCL C
124*6fee86a4SJeremy Kemp  * compiled to request OpenCL 2.0 compilation of kernels with 1.2 as
125*6fee86a4SJeremy Kemp  * the default in the absence of the flag.
126*6fee86a4SJeremy Kemp  * In some cases the C++ bindings automatically compile code for ease.
127*6fee86a4SJeremy Kemp  * For those cases the compilation defaults to OpenCL C 2.0.
128*6fee86a4SJeremy Kemp  * If this is not wanted, the CL_HPP_CL_1_2_DEFAULT_BUILD macro may
129*6fee86a4SJeremy Kemp  * be specified to assume 1.2 compilation.
130*6fee86a4SJeremy Kemp  * If more fine-grained decisions on a per-kernel bases are required
131*6fee86a4SJeremy Kemp  * then explicit build operations that take the flag should be used.
132*6fee86a4SJeremy Kemp  *
133*6fee86a4SJeremy Kemp  *
134*6fee86a4SJeremy Kemp  * \section parameterization Parameters
135*6fee86a4SJeremy Kemp  * This header may be parameterized by a set of preprocessor macros.
136*6fee86a4SJeremy Kemp  *
137*6fee86a4SJeremy Kemp  * - CL_HPP_TARGET_OPENCL_VERSION
138*6fee86a4SJeremy Kemp  *
139*6fee86a4SJeremy Kemp  *   Defines the target OpenCL runtime version to build the header
140*6fee86a4SJeremy Kemp  *   against. Defaults to 300, representing OpenCL 3.0.
141*6fee86a4SJeremy Kemp  *
142*6fee86a4SJeremy Kemp  * - CL_HPP_MINIMUM_OPENCL_VERSION
143*6fee86a4SJeremy Kemp  *
144*6fee86a4SJeremy Kemp  *   Defines the minimum OpenCL runtime version to build the header
145*6fee86a4SJeremy Kemp  *   against. Defaults to 200, representing OpenCL 2.0.
146*6fee86a4SJeremy Kemp  *
147*6fee86a4SJeremy Kemp  * - CL_HPP_NO_STD_STRING
148*6fee86a4SJeremy Kemp  *
149*6fee86a4SJeremy Kemp  *   Do not use the standard library string class. cl::string is not
150*6fee86a4SJeremy Kemp  *   defined and may be defined by the user before opencl.hpp is
151*6fee86a4SJeremy Kemp  *   included.
152*6fee86a4SJeremy Kemp  *
153*6fee86a4SJeremy Kemp  * - CL_HPP_NO_STD_VECTOR
154*6fee86a4SJeremy Kemp  *
155*6fee86a4SJeremy Kemp  *   Do not use the standard library vector class. cl::vector is not
156*6fee86a4SJeremy Kemp  *   defined and may be defined by the user before opencl.hpp is
157*6fee86a4SJeremy Kemp  *   included.
158*6fee86a4SJeremy Kemp  *
159*6fee86a4SJeremy Kemp  * - CL_HPP_NO_STD_ARRAY
160*6fee86a4SJeremy Kemp  *
161*6fee86a4SJeremy Kemp  *   Do not use the standard library array class. cl::array is not
162*6fee86a4SJeremy Kemp  *   defined and may be defined by the user before opencl.hpp is
163*6fee86a4SJeremy Kemp  *   included.
164*6fee86a4SJeremy Kemp  *
165*6fee86a4SJeremy Kemp  * - CL_HPP_NO_STD_UNIQUE_PTR
166*6fee86a4SJeremy Kemp  *
167*6fee86a4SJeremy Kemp  *   Do not use the standard library unique_ptr class. cl::pointer and
168*6fee86a4SJeremy Kemp  *   the cl::allocate_pointer functions are not defined and may be
169*6fee86a4SJeremy Kemp  *   defined by the user before opencl.hpp is included.
170*6fee86a4SJeremy Kemp  *
171*6fee86a4SJeremy Kemp  * - CL_HPP_ENABLE_EXCEPTIONS
172*6fee86a4SJeremy Kemp  *
173*6fee86a4SJeremy Kemp  *   Enable exceptions for use in the C++ bindings header. This is the
174*6fee86a4SJeremy Kemp  *   preferred error handling mechanism but is not required.
175*6fee86a4SJeremy Kemp  *
176*6fee86a4SJeremy Kemp  * - CL_HPP_ENABLE_SIZE_T_COMPATIBILITY
177*6fee86a4SJeremy Kemp  *
178*6fee86a4SJeremy Kemp  *   Backward compatibility option to support cl.hpp-style size_t
179*6fee86a4SJeremy Kemp  *   class.  Replaces the updated std::array derived version and
180*6fee86a4SJeremy Kemp  *   removal of size_t from the namespace. Note that in this case the
181*6fee86a4SJeremy Kemp  *   new size_t class is placed in the cl::compatibility namespace and
182*6fee86a4SJeremy Kemp  *   thus requires an additional using declaration for direct backward
183*6fee86a4SJeremy Kemp  *   compatibility.
184*6fee86a4SJeremy Kemp  *
185*6fee86a4SJeremy Kemp  * - CL_HPP_ENABLE_PROGRAM_CONSTRUCTION_FROM_ARRAY_COMPATIBILITY
186*6fee86a4SJeremy Kemp  *
187*6fee86a4SJeremy Kemp  *   Enable older vector of pairs interface for construction of
188*6fee86a4SJeremy Kemp  *   programs.
189*6fee86a4SJeremy Kemp  *
190*6fee86a4SJeremy Kemp  * - CL_HPP_CL_1_2_DEFAULT_BUILD
191*6fee86a4SJeremy Kemp  *
192*6fee86a4SJeremy Kemp  *   Default to OpenCL C 1.2 compilation rather than OpenCL C 2.0
193*6fee86a4SJeremy Kemp  *   applies to use of cl::Program construction and other program
194*6fee86a4SJeremy Kemp  *   build variants.
195*6fee86a4SJeremy Kemp  *
196*6fee86a4SJeremy Kemp  *
197*6fee86a4SJeremy Kemp  * - CL_HPP_USE_CL_SUB_GROUPS_KHR
198*6fee86a4SJeremy Kemp  *
199*6fee86a4SJeremy Kemp  *   Enable the cl_khr_subgroups extension.
200*6fee86a4SJeremy Kemp  *
201*6fee86a4SJeremy Kemp  * - CL_HPP_USE_DX_INTEROP
202*6fee86a4SJeremy Kemp  *
203*6fee86a4SJeremy Kemp  *   Enable the cl_khr_d3d10_sharing extension.
204*6fee86a4SJeremy Kemp  *
205*6fee86a4SJeremy Kemp  * - CL_HPP_USE_IL_KHR
206*6fee86a4SJeremy Kemp  *
207*6fee86a4SJeremy Kemp  *   Enable the cl_khr_il_program extension.
208*6fee86a4SJeremy Kemp  *
209*6fee86a4SJeremy Kemp  *
210*6fee86a4SJeremy Kemp  * \section example Example
211*6fee86a4SJeremy Kemp  *
212*6fee86a4SJeremy Kemp  * The following example shows a general use case for the C++
213*6fee86a4SJeremy Kemp  * bindings, including support for the optional exception feature and
214*6fee86a4SJeremy Kemp  * also the supplied vector and string classes, see following sections for
215*6fee86a4SJeremy Kemp  * decriptions of these features.
216*6fee86a4SJeremy Kemp  *
217*6fee86a4SJeremy Kemp  * Note: the C++ bindings use std::call_once and therefore may need to be
218*6fee86a4SJeremy Kemp  * compiled using special command-line options (such as "-pthread") on some
219*6fee86a4SJeremy Kemp  * platforms!
220*6fee86a4SJeremy Kemp  *
221*6fee86a4SJeremy Kemp  * \code
222*6fee86a4SJeremy Kemp     #define CL_HPP_ENABLE_EXCEPTIONS
223*6fee86a4SJeremy Kemp     #define CL_HPP_TARGET_OPENCL_VERSION 200
224*6fee86a4SJeremy Kemp 
225*6fee86a4SJeremy Kemp     #include <CL/opencl.hpp>
226*6fee86a4SJeremy Kemp     #include <iostream>
227*6fee86a4SJeremy Kemp     #include <vector>
228*6fee86a4SJeremy Kemp     #include <memory>
229*6fee86a4SJeremy Kemp     #include <algorithm>
230*6fee86a4SJeremy Kemp 
231*6fee86a4SJeremy Kemp     const int numElements = 32;
232*6fee86a4SJeremy Kemp 
233*6fee86a4SJeremy Kemp     int main(void)
234*6fee86a4SJeremy Kemp     {
235*6fee86a4SJeremy Kemp         // Filter for a 2.0 or newer platform and set it as the default
236*6fee86a4SJeremy Kemp         std::vector<cl::Platform> platforms;
237*6fee86a4SJeremy Kemp         cl::Platform::get(&platforms);
238*6fee86a4SJeremy Kemp         cl::Platform plat;
239*6fee86a4SJeremy Kemp         for (auto &p : platforms) {
240*6fee86a4SJeremy Kemp             std::string platver = p.getInfo<CL_PLATFORM_VERSION>();
241*6fee86a4SJeremy Kemp             if (platver.find("OpenCL 2.") != std::string::npos ||
242*6fee86a4SJeremy Kemp                 platver.find("OpenCL 3.") != std::string::npos) {
243*6fee86a4SJeremy Kemp                 // Note: an OpenCL 3.x platform may not support all required features!
244*6fee86a4SJeremy Kemp                 plat = p;
245*6fee86a4SJeremy Kemp             }
246*6fee86a4SJeremy Kemp         }
247*6fee86a4SJeremy Kemp         if (plat() == 0) {
248*6fee86a4SJeremy Kemp             std::cout << "No OpenCL 2.0 or newer platform found.\n";
249*6fee86a4SJeremy Kemp             return -1;
250*6fee86a4SJeremy Kemp         }
251*6fee86a4SJeremy Kemp 
252*6fee86a4SJeremy Kemp         cl::Platform newP = cl::Platform::setDefault(plat);
253*6fee86a4SJeremy Kemp         if (newP != plat) {
254*6fee86a4SJeremy Kemp             std::cout << "Error setting default platform.\n";
255*6fee86a4SJeremy Kemp             return -1;
256*6fee86a4SJeremy Kemp         }
257*6fee86a4SJeremy Kemp 
258*6fee86a4SJeremy Kemp         // C++11 raw string literal for the first kernel
259*6fee86a4SJeremy Kemp         std::string kernel1{R"CLC(
260*6fee86a4SJeremy Kemp             global int globalA;
261*6fee86a4SJeremy Kemp             kernel void updateGlobal()
262*6fee86a4SJeremy Kemp             {
263*6fee86a4SJeremy Kemp               globalA = 75;
264*6fee86a4SJeremy Kemp             }
265*6fee86a4SJeremy Kemp         )CLC"};
266*6fee86a4SJeremy Kemp 
267*6fee86a4SJeremy Kemp         // Raw string literal for the second kernel
268*6fee86a4SJeremy Kemp         std::string kernel2{R"CLC(
269*6fee86a4SJeremy Kemp             typedef struct { global int *bar; } Foo;
270*6fee86a4SJeremy Kemp             kernel void vectorAdd(global const Foo* aNum, global const int *inputA, global const int *inputB,
271*6fee86a4SJeremy Kemp                                   global int *output, int val, write_only pipe int outPipe, queue_t childQueue)
272*6fee86a4SJeremy Kemp             {
273*6fee86a4SJeremy Kemp               output[get_global_id(0)] = inputA[get_global_id(0)] + inputB[get_global_id(0)] + val + *(aNum->bar);
274*6fee86a4SJeremy Kemp               write_pipe(outPipe, &val);
275*6fee86a4SJeremy Kemp               queue_t default_queue = get_default_queue();
276*6fee86a4SJeremy Kemp               ndrange_t ndrange = ndrange_1D(get_global_size(0)/2, get_global_size(0)/2);
277*6fee86a4SJeremy Kemp 
278*6fee86a4SJeremy Kemp               // Have a child kernel write into third quarter of output
279*6fee86a4SJeremy Kemp               enqueue_kernel(default_queue, CLK_ENQUEUE_FLAGS_WAIT_KERNEL, ndrange,
280*6fee86a4SJeremy Kemp                 ^{
281*6fee86a4SJeremy Kemp                     output[get_global_size(0)*2 + get_global_id(0)] =
282*6fee86a4SJeremy Kemp                       inputA[get_global_size(0)*2 + get_global_id(0)] + inputB[get_global_size(0)*2 + get_global_id(0)] + globalA;
283*6fee86a4SJeremy Kemp                 });
284*6fee86a4SJeremy Kemp 
285*6fee86a4SJeremy Kemp               // Have a child kernel write into last quarter of output
286*6fee86a4SJeremy Kemp               enqueue_kernel(childQueue, CLK_ENQUEUE_FLAGS_WAIT_KERNEL, ndrange,
287*6fee86a4SJeremy Kemp                 ^{
288*6fee86a4SJeremy Kemp                     output[get_global_size(0)*3 + get_global_id(0)] =
289*6fee86a4SJeremy Kemp                       inputA[get_global_size(0)*3 + get_global_id(0)] + inputB[get_global_size(0)*3 + get_global_id(0)] + globalA + 2;
290*6fee86a4SJeremy Kemp                 });
291*6fee86a4SJeremy Kemp             }
292*6fee86a4SJeremy Kemp         )CLC"};
293*6fee86a4SJeremy Kemp 
294*6fee86a4SJeremy Kemp         std::vector<std::string> programStrings;
295*6fee86a4SJeremy Kemp         programStrings.push_back(kernel1);
296*6fee86a4SJeremy Kemp         programStrings.push_back(kernel2);
297*6fee86a4SJeremy Kemp 
298*6fee86a4SJeremy Kemp         cl::Program vectorAddProgram(programStrings);
299*6fee86a4SJeremy Kemp         try {
300*6fee86a4SJeremy Kemp             vectorAddProgram.build("-cl-std=CL2.0");
301*6fee86a4SJeremy Kemp         }
302*6fee86a4SJeremy Kemp         catch (...) {
303*6fee86a4SJeremy Kemp             // Print build info for all devices
304*6fee86a4SJeremy Kemp             cl_int buildErr = CL_SUCCESS;
305*6fee86a4SJeremy Kemp             auto buildInfo = vectorAddProgram.getBuildInfo<CL_PROGRAM_BUILD_LOG>(&buildErr);
306*6fee86a4SJeremy Kemp             for (auto &pair : buildInfo) {
307*6fee86a4SJeremy Kemp                 std::cerr << pair.second << std::endl << std::endl;
308*6fee86a4SJeremy Kemp             }
309*6fee86a4SJeremy Kemp 
310*6fee86a4SJeremy Kemp             return 1;
311*6fee86a4SJeremy Kemp         }
312*6fee86a4SJeremy Kemp 
313*6fee86a4SJeremy Kemp         typedef struct { int *bar; } Foo;
314*6fee86a4SJeremy Kemp 
315*6fee86a4SJeremy Kemp         // Get and run kernel that initializes the program-scope global
316*6fee86a4SJeremy Kemp         // A test for kernels that take no arguments
317*6fee86a4SJeremy Kemp         auto program2Kernel =
318*6fee86a4SJeremy Kemp             cl::KernelFunctor<>(vectorAddProgram, "updateGlobal");
319*6fee86a4SJeremy Kemp         program2Kernel(
320*6fee86a4SJeremy Kemp             cl::EnqueueArgs(
321*6fee86a4SJeremy Kemp             cl::NDRange(1)));
322*6fee86a4SJeremy Kemp 
323*6fee86a4SJeremy Kemp         //////////////////
324*6fee86a4SJeremy Kemp         // SVM allocations
325*6fee86a4SJeremy Kemp 
326*6fee86a4SJeremy Kemp         auto anSVMInt = cl::allocate_svm<int, cl::SVMTraitCoarse<>>();
327*6fee86a4SJeremy Kemp         *anSVMInt = 5;
328*6fee86a4SJeremy Kemp         cl::SVMAllocator<Foo, cl::SVMTraitCoarse<cl::SVMTraitReadOnly<>>> svmAllocReadOnly;
329*6fee86a4SJeremy Kemp         auto fooPointer = cl::allocate_pointer<Foo>(svmAllocReadOnly);
330*6fee86a4SJeremy Kemp         fooPointer->bar = anSVMInt.get();
331*6fee86a4SJeremy Kemp         cl::SVMAllocator<int, cl::SVMTraitCoarse<>> svmAlloc;
332*6fee86a4SJeremy Kemp         std::vector<int, cl::SVMAllocator<int, cl::SVMTraitCoarse<>>> inputA(numElements, 1, svmAlloc);
333*6fee86a4SJeremy Kemp         cl::coarse_svm_vector<int> inputB(numElements, 2, svmAlloc);
334*6fee86a4SJeremy Kemp 
335*6fee86a4SJeremy Kemp         //////////////
336*6fee86a4SJeremy Kemp         // Traditional cl_mem allocations
337*6fee86a4SJeremy Kemp 
338*6fee86a4SJeremy Kemp         std::vector<int> output(numElements, 0xdeadbeef);
339*6fee86a4SJeremy Kemp         cl::Buffer outputBuffer(output.begin(), output.end(), false);
340*6fee86a4SJeremy Kemp         cl::Pipe aPipe(sizeof(cl_int), numElements / 2);
341*6fee86a4SJeremy Kemp 
342*6fee86a4SJeremy Kemp         // Default command queue, also passed in as a parameter
343*6fee86a4SJeremy Kemp         cl::DeviceCommandQueue defaultDeviceQueue = cl::DeviceCommandQueue::makeDefault(
344*6fee86a4SJeremy Kemp             cl::Context::getDefault(), cl::Device::getDefault());
345*6fee86a4SJeremy Kemp 
346*6fee86a4SJeremy Kemp         auto vectorAddKernel =
347*6fee86a4SJeremy Kemp             cl::KernelFunctor<
348*6fee86a4SJeremy Kemp                 decltype(fooPointer)&,
349*6fee86a4SJeremy Kemp                 int*,
350*6fee86a4SJeremy Kemp                 cl::coarse_svm_vector<int>&,
351*6fee86a4SJeremy Kemp                 cl::Buffer,
352*6fee86a4SJeremy Kemp                 int,
353*6fee86a4SJeremy Kemp                 cl::Pipe&,
354*6fee86a4SJeremy Kemp                 cl::DeviceCommandQueue
355*6fee86a4SJeremy Kemp                 >(vectorAddProgram, "vectorAdd");
356*6fee86a4SJeremy Kemp 
357*6fee86a4SJeremy Kemp         // Ensure that the additional SVM pointer is available to the kernel
358*6fee86a4SJeremy Kemp         // This one was not passed as a parameter
359*6fee86a4SJeremy Kemp         vectorAddKernel.setSVMPointers(anSVMInt);
360*6fee86a4SJeremy Kemp 
361*6fee86a4SJeremy Kemp         cl_int error;
362*6fee86a4SJeremy Kemp         vectorAddKernel(
363*6fee86a4SJeremy Kemp             cl::EnqueueArgs(
364*6fee86a4SJeremy Kemp                 cl::NDRange(numElements/2),
365*6fee86a4SJeremy Kemp                 cl::NDRange(numElements/2)),
366*6fee86a4SJeremy Kemp             fooPointer,
367*6fee86a4SJeremy Kemp             inputA.data(),
368*6fee86a4SJeremy Kemp             inputB,
369*6fee86a4SJeremy Kemp             outputBuffer,
370*6fee86a4SJeremy Kemp             3,
371*6fee86a4SJeremy Kemp             aPipe,
372*6fee86a4SJeremy Kemp             defaultDeviceQueue,
373*6fee86a4SJeremy Kemp             error
374*6fee86a4SJeremy Kemp             );
375*6fee86a4SJeremy Kemp 
376*6fee86a4SJeremy Kemp         cl::copy(outputBuffer, output.begin(), output.end());
377*6fee86a4SJeremy Kemp 
378*6fee86a4SJeremy Kemp         cl::Device d = cl::Device::getDefault();
379*6fee86a4SJeremy Kemp 
380*6fee86a4SJeremy Kemp         std::cout << "Output:\n";
381*6fee86a4SJeremy Kemp         for (int i = 1; i < numElements; ++i) {
382*6fee86a4SJeremy Kemp             std::cout << "\t" << output[i] << "\n";
383*6fee86a4SJeremy Kemp         }
384*6fee86a4SJeremy Kemp         std::cout << "\n\n";
385*6fee86a4SJeremy Kemp 
386*6fee86a4SJeremy Kemp         return 0;
387*6fee86a4SJeremy Kemp     }
388*6fee86a4SJeremy Kemp  *
389*6fee86a4SJeremy Kemp  * \endcode
390*6fee86a4SJeremy Kemp  *
391*6fee86a4SJeremy Kemp  */
392*6fee86a4SJeremy Kemp #ifndef CL_HPP_
393*6fee86a4SJeremy Kemp #define CL_HPP_
394*6fee86a4SJeremy Kemp 
395*6fee86a4SJeremy Kemp /* Handle deprecated preprocessor definitions. In each case, we only check for
396*6fee86a4SJeremy Kemp  * the old name if the new name is not defined, so that user code can define
397*6fee86a4SJeremy Kemp  * both and hence work with either version of the bindings.
398*6fee86a4SJeremy Kemp  */
399*6fee86a4SJeremy Kemp #if !defined(CL_HPP_USE_DX_INTEROP) && defined(USE_DX_INTEROP)
400*6fee86a4SJeremy Kemp # pragma message("opencl.hpp: USE_DX_INTEROP is deprecated. Define CL_HPP_USE_DX_INTEROP instead")
401*6fee86a4SJeremy Kemp # define CL_HPP_USE_DX_INTEROP
402*6fee86a4SJeremy Kemp #endif
403*6fee86a4SJeremy Kemp #if !defined(CL_HPP_ENABLE_EXCEPTIONS) && defined(__CL_ENABLE_EXCEPTIONS)
404*6fee86a4SJeremy Kemp # pragma message("opencl.hpp: __CL_ENABLE_EXCEPTIONS is deprecated. Define CL_HPP_ENABLE_EXCEPTIONS instead")
405*6fee86a4SJeremy Kemp # define CL_HPP_ENABLE_EXCEPTIONS
406*6fee86a4SJeremy Kemp #endif
407*6fee86a4SJeremy Kemp #if !defined(CL_HPP_NO_STD_VECTOR) && defined(__NO_STD_VECTOR)
408*6fee86a4SJeremy Kemp # pragma message("opencl.hpp: __NO_STD_VECTOR is deprecated. Define CL_HPP_NO_STD_VECTOR instead")
409*6fee86a4SJeremy Kemp # define CL_HPP_NO_STD_VECTOR
410*6fee86a4SJeremy Kemp #endif
411*6fee86a4SJeremy Kemp #if !defined(CL_HPP_NO_STD_STRING) && defined(__NO_STD_STRING)
412*6fee86a4SJeremy Kemp # pragma message("opencl.hpp: __NO_STD_STRING is deprecated. Define CL_HPP_NO_STD_STRING instead")
413*6fee86a4SJeremy Kemp # define CL_HPP_NO_STD_STRING
414*6fee86a4SJeremy Kemp #endif
415*6fee86a4SJeremy Kemp #if defined(VECTOR_CLASS)
416*6fee86a4SJeremy Kemp # pragma message("opencl.hpp: VECTOR_CLASS is deprecated. Alias cl::vector instead")
417*6fee86a4SJeremy Kemp #endif
418*6fee86a4SJeremy Kemp #if defined(STRING_CLASS)
419*6fee86a4SJeremy Kemp # pragma message("opencl.hpp: STRING_CLASS is deprecated. Alias cl::string instead.")
420*6fee86a4SJeremy Kemp #endif
421*6fee86a4SJeremy Kemp #if !defined(CL_HPP_USER_OVERRIDE_ERROR_STRINGS) && defined(__CL_USER_OVERRIDE_ERROR_STRINGS)
422*6fee86a4SJeremy Kemp # pragma message("opencl.hpp: __CL_USER_OVERRIDE_ERROR_STRINGS is deprecated. Define CL_HPP_USER_OVERRIDE_ERROR_STRINGS instead")
423*6fee86a4SJeremy Kemp # define CL_HPP_USER_OVERRIDE_ERROR_STRINGS
424*6fee86a4SJeremy Kemp #endif
425*6fee86a4SJeremy Kemp 
426*6fee86a4SJeremy Kemp /* Warn about features that are no longer supported
427*6fee86a4SJeremy Kemp  */
428*6fee86a4SJeremy Kemp #if defined(__USE_DEV_VECTOR)
429*6fee86a4SJeremy Kemp # pragma message("opencl.hpp: __USE_DEV_VECTOR is no longer supported. Expect compilation errors")
430*6fee86a4SJeremy Kemp #endif
431*6fee86a4SJeremy Kemp #if defined(__USE_DEV_STRING)
432*6fee86a4SJeremy Kemp # pragma message("opencl.hpp: __USE_DEV_STRING is no longer supported. Expect compilation errors")
433*6fee86a4SJeremy Kemp #endif
434*6fee86a4SJeremy Kemp 
435*6fee86a4SJeremy Kemp /* Detect which version to target */
436*6fee86a4SJeremy Kemp #if !defined(CL_HPP_TARGET_OPENCL_VERSION)
437*6fee86a4SJeremy Kemp # pragma message("opencl.hpp: CL_HPP_TARGET_OPENCL_VERSION is not defined. It will default to 300 (OpenCL 3.0)")
438*6fee86a4SJeremy Kemp # define CL_HPP_TARGET_OPENCL_VERSION 300
439*6fee86a4SJeremy Kemp #endif
440*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION != 100 && \
441*6fee86a4SJeremy Kemp     CL_HPP_TARGET_OPENCL_VERSION != 110 && \
442*6fee86a4SJeremy Kemp     CL_HPP_TARGET_OPENCL_VERSION != 120 && \
443*6fee86a4SJeremy Kemp     CL_HPP_TARGET_OPENCL_VERSION != 200 && \
444*6fee86a4SJeremy Kemp     CL_HPP_TARGET_OPENCL_VERSION != 210 && \
445*6fee86a4SJeremy Kemp     CL_HPP_TARGET_OPENCL_VERSION != 220 && \
446*6fee86a4SJeremy Kemp     CL_HPP_TARGET_OPENCL_VERSION != 300
447*6fee86a4SJeremy Kemp # pragma message("opencl.hpp: CL_HPP_TARGET_OPENCL_VERSION is not a valid value (100, 110, 120, 200, 210, 220 or 300). It will be set to 300 (OpenCL 3.0).")
448*6fee86a4SJeremy Kemp # undef CL_HPP_TARGET_OPENCL_VERSION
449*6fee86a4SJeremy Kemp # define CL_HPP_TARGET_OPENCL_VERSION 300
450*6fee86a4SJeremy Kemp #endif
451*6fee86a4SJeremy Kemp 
452*6fee86a4SJeremy Kemp /* Forward target OpenCL version to C headers if necessary */
453*6fee86a4SJeremy Kemp #if defined(CL_TARGET_OPENCL_VERSION)
454*6fee86a4SJeremy Kemp /* Warn if prior definition of CL_TARGET_OPENCL_VERSION is lower than
455*6fee86a4SJeremy Kemp  * requested C++ bindings version */
456*6fee86a4SJeremy Kemp #if CL_TARGET_OPENCL_VERSION < CL_HPP_TARGET_OPENCL_VERSION
457*6fee86a4SJeremy Kemp # pragma message("CL_TARGET_OPENCL_VERSION is already defined as is lower than CL_HPP_TARGET_OPENCL_VERSION")
458*6fee86a4SJeremy Kemp #endif
459*6fee86a4SJeremy Kemp #else
460*6fee86a4SJeremy Kemp # define CL_TARGET_OPENCL_VERSION CL_HPP_TARGET_OPENCL_VERSION
461*6fee86a4SJeremy Kemp #endif
462*6fee86a4SJeremy Kemp 
463*6fee86a4SJeremy Kemp #if !defined(CL_HPP_MINIMUM_OPENCL_VERSION)
464*6fee86a4SJeremy Kemp # define CL_HPP_MINIMUM_OPENCL_VERSION 200
465*6fee86a4SJeremy Kemp #endif
466*6fee86a4SJeremy Kemp #if CL_HPP_MINIMUM_OPENCL_VERSION != 100 && \
467*6fee86a4SJeremy Kemp     CL_HPP_MINIMUM_OPENCL_VERSION != 110 && \
468*6fee86a4SJeremy Kemp     CL_HPP_MINIMUM_OPENCL_VERSION != 120 && \
469*6fee86a4SJeremy Kemp     CL_HPP_MINIMUM_OPENCL_VERSION != 200 && \
470*6fee86a4SJeremy Kemp     CL_HPP_MINIMUM_OPENCL_VERSION != 210 && \
471*6fee86a4SJeremy Kemp     CL_HPP_MINIMUM_OPENCL_VERSION != 220 && \
472*6fee86a4SJeremy Kemp     CL_HPP_MINIMUM_OPENCL_VERSION != 300
473*6fee86a4SJeremy Kemp # pragma message("opencl.hpp: CL_HPP_MINIMUM_OPENCL_VERSION is not a valid value (100, 110, 120, 200, 210, 220 or 300). It will be set to 100")
474*6fee86a4SJeremy Kemp # undef CL_HPP_MINIMUM_OPENCL_VERSION
475*6fee86a4SJeremy Kemp # define CL_HPP_MINIMUM_OPENCL_VERSION 100
476*6fee86a4SJeremy Kemp #endif
477*6fee86a4SJeremy Kemp #if CL_HPP_MINIMUM_OPENCL_VERSION > CL_HPP_TARGET_OPENCL_VERSION
478*6fee86a4SJeremy Kemp # error "CL_HPP_MINIMUM_OPENCL_VERSION must not be greater than CL_HPP_TARGET_OPENCL_VERSION"
479*6fee86a4SJeremy Kemp #endif
480*6fee86a4SJeremy Kemp 
481*6fee86a4SJeremy Kemp #if CL_HPP_MINIMUM_OPENCL_VERSION <= 100 && !defined(CL_USE_DEPRECATED_OPENCL_1_0_APIS)
482*6fee86a4SJeremy Kemp # define CL_USE_DEPRECATED_OPENCL_1_0_APIS
483*6fee86a4SJeremy Kemp #endif
484*6fee86a4SJeremy Kemp #if CL_HPP_MINIMUM_OPENCL_VERSION <= 110 && !defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS)
485*6fee86a4SJeremy Kemp # define CL_USE_DEPRECATED_OPENCL_1_1_APIS
486*6fee86a4SJeremy Kemp #endif
487*6fee86a4SJeremy Kemp #if CL_HPP_MINIMUM_OPENCL_VERSION <= 120 && !defined(CL_USE_DEPRECATED_OPENCL_1_2_APIS)
488*6fee86a4SJeremy Kemp # define CL_USE_DEPRECATED_OPENCL_1_2_APIS
489*6fee86a4SJeremy Kemp #endif
490*6fee86a4SJeremy Kemp #if CL_HPP_MINIMUM_OPENCL_VERSION <= 200 && !defined(CL_USE_DEPRECATED_OPENCL_2_0_APIS)
491*6fee86a4SJeremy Kemp # define CL_USE_DEPRECATED_OPENCL_2_0_APIS
492*6fee86a4SJeremy Kemp #endif
493*6fee86a4SJeremy Kemp #if CL_HPP_MINIMUM_OPENCL_VERSION <= 210 && !defined(CL_USE_DEPRECATED_OPENCL_2_1_APIS)
494*6fee86a4SJeremy Kemp # define CL_USE_DEPRECATED_OPENCL_2_1_APIS
495*6fee86a4SJeremy Kemp #endif
496*6fee86a4SJeremy Kemp #if CL_HPP_MINIMUM_OPENCL_VERSION <= 220 && !defined(CL_USE_DEPRECATED_OPENCL_2_2_APIS)
497*6fee86a4SJeremy Kemp # define CL_USE_DEPRECATED_OPENCL_2_2_APIS
498*6fee86a4SJeremy Kemp #endif
499*6fee86a4SJeremy Kemp 
500*6fee86a4SJeremy Kemp #ifdef _WIN32
501*6fee86a4SJeremy Kemp 
502*6fee86a4SJeremy Kemp #include <malloc.h>
503*6fee86a4SJeremy Kemp 
504*6fee86a4SJeremy Kemp #if defined(CL_HPP_USE_DX_INTEROP)
505*6fee86a4SJeremy Kemp #include <CL/cl_d3d10.h>
506*6fee86a4SJeremy Kemp #include <CL/cl_dx9_media_sharing.h>
507*6fee86a4SJeremy Kemp #endif
508*6fee86a4SJeremy Kemp #endif // _WIN32
509*6fee86a4SJeremy Kemp 
510*6fee86a4SJeremy Kemp #if defined(_MSC_VER)
511*6fee86a4SJeremy Kemp #include <intrin.h>
512*6fee86a4SJeremy Kemp #endif // _MSC_VER
513*6fee86a4SJeremy Kemp 
514*6fee86a4SJeremy Kemp  // Check for a valid C++ version
515*6fee86a4SJeremy Kemp 
516*6fee86a4SJeremy Kemp // Need to do both tests here because for some reason __cplusplus is not
517*6fee86a4SJeremy Kemp // updated in visual studio
518*6fee86a4SJeremy Kemp #if (!defined(_MSC_VER) && __cplusplus < 201103L) || (defined(_MSC_VER) && _MSC_VER < 1700)
519*6fee86a4SJeremy Kemp #error Visual studio 2013 or another C++11-supporting compiler required
520*6fee86a4SJeremy Kemp #endif
521*6fee86a4SJeremy Kemp 
522*6fee86a4SJeremy Kemp #if defined(__APPLE__) || defined(__MACOSX)
523*6fee86a4SJeremy Kemp #include <OpenCL/opencl.h>
524*6fee86a4SJeremy Kemp #else
525*6fee86a4SJeremy Kemp #include <CL/opencl.h>
526*6fee86a4SJeremy Kemp #endif // !__APPLE__
527*6fee86a4SJeremy Kemp 
528*6fee86a4SJeremy Kemp #if __cplusplus >= 201703L
529*6fee86a4SJeremy Kemp # define CL_HPP_DEFINE_STATIC_MEMBER_ inline
530*6fee86a4SJeremy Kemp #elif defined(_MSC_VER)
531*6fee86a4SJeremy Kemp # define CL_HPP_DEFINE_STATIC_MEMBER_ __declspec(selectany)
532*6fee86a4SJeremy Kemp #elif defined(__MINGW32__)
533*6fee86a4SJeremy Kemp # define CL_HPP_DEFINE_STATIC_MEMBER_ __attribute__((selectany))
534*6fee86a4SJeremy Kemp #else
535*6fee86a4SJeremy Kemp # define CL_HPP_DEFINE_STATIC_MEMBER_ __attribute__((weak))
536*6fee86a4SJeremy Kemp #endif // !_MSC_VER
537*6fee86a4SJeremy Kemp 
538*6fee86a4SJeremy Kemp // Define deprecated prefixes and suffixes to ensure compilation
539*6fee86a4SJeremy Kemp // in case they are not pre-defined
540*6fee86a4SJeremy Kemp #if !defined(CL_API_PREFIX__VERSION_1_1_DEPRECATED)
541*6fee86a4SJeremy Kemp #define CL_API_PREFIX__VERSION_1_1_DEPRECATED
542*6fee86a4SJeremy Kemp #endif // #if !defined(CL_API_PREFIX__VERSION_1_1_DEPRECATED)
543*6fee86a4SJeremy Kemp #if !defined(CL_API_SUFFIX__VERSION_1_1_DEPRECATED)
544*6fee86a4SJeremy Kemp #define CL_API_SUFFIX__VERSION_1_1_DEPRECATED
545*6fee86a4SJeremy Kemp #endif // #if !defined(CL_API_SUFFIX__VERSION_1_1_DEPRECATED)
546*6fee86a4SJeremy Kemp 
547*6fee86a4SJeremy Kemp #if !defined(CL_API_PREFIX__VERSION_1_2_DEPRECATED)
548*6fee86a4SJeremy Kemp #define CL_API_PREFIX__VERSION_1_2_DEPRECATED
549*6fee86a4SJeremy Kemp #endif // #if !defined(CL_API_PREFIX__VERSION_1_2_DEPRECATED)
550*6fee86a4SJeremy Kemp #if !defined(CL_API_SUFFIX__VERSION_1_2_DEPRECATED)
551*6fee86a4SJeremy Kemp #define CL_API_SUFFIX__VERSION_1_2_DEPRECATED
552*6fee86a4SJeremy Kemp #endif // #if !defined(CL_API_SUFFIX__VERSION_1_2_DEPRECATED)
553*6fee86a4SJeremy Kemp 
554*6fee86a4SJeremy Kemp #if !defined(CL_API_PREFIX__VERSION_2_2_DEPRECATED)
555*6fee86a4SJeremy Kemp #define CL_API_PREFIX__VERSION_2_2_DEPRECATED
556*6fee86a4SJeremy Kemp #endif // #if !defined(CL_API_PREFIX__VERSION_2_2_DEPRECATED)
557*6fee86a4SJeremy Kemp #if !defined(CL_API_SUFFIX__VERSION_2_2_DEPRECATED)
558*6fee86a4SJeremy Kemp #define CL_API_SUFFIX__VERSION_2_2_DEPRECATED
559*6fee86a4SJeremy Kemp #endif // #if !defined(CL_API_SUFFIX__VERSION_2_2_DEPRECATED)
560*6fee86a4SJeremy Kemp 
561*6fee86a4SJeremy Kemp #if !defined(CL_CALLBACK)
562*6fee86a4SJeremy Kemp #define CL_CALLBACK
563*6fee86a4SJeremy Kemp #endif //CL_CALLBACK
564*6fee86a4SJeremy Kemp 
565*6fee86a4SJeremy Kemp #include <utility>
566*6fee86a4SJeremy Kemp #include <limits>
567*6fee86a4SJeremy Kemp #include <iterator>
568*6fee86a4SJeremy Kemp #include <mutex>
569*6fee86a4SJeremy Kemp #include <cstring>
570*6fee86a4SJeremy Kemp #include <functional>
571*6fee86a4SJeremy Kemp 
572*6fee86a4SJeremy Kemp 
573*6fee86a4SJeremy Kemp // Define a size_type to represent a correctly resolved size_t
574*6fee86a4SJeremy Kemp #if defined(CL_HPP_ENABLE_SIZE_T_COMPATIBILITY)
575*6fee86a4SJeremy Kemp namespace cl {
576*6fee86a4SJeremy Kemp     using size_type = ::size_t;
577*6fee86a4SJeremy Kemp } // namespace cl
578*6fee86a4SJeremy Kemp #else // #if defined(CL_HPP_ENABLE_SIZE_T_COMPATIBILITY)
579*6fee86a4SJeremy Kemp namespace cl {
580*6fee86a4SJeremy Kemp     using size_type = size_t;
581*6fee86a4SJeremy Kemp } // namespace cl
582*6fee86a4SJeremy Kemp #endif // #if defined(CL_HPP_ENABLE_SIZE_T_COMPATIBILITY)
583*6fee86a4SJeremy Kemp 
584*6fee86a4SJeremy Kemp 
585*6fee86a4SJeremy Kemp #if defined(CL_HPP_ENABLE_EXCEPTIONS)
586*6fee86a4SJeremy Kemp #include <exception>
587*6fee86a4SJeremy Kemp #endif // #if defined(CL_HPP_ENABLE_EXCEPTIONS)
588*6fee86a4SJeremy Kemp 
589*6fee86a4SJeremy Kemp #if !defined(CL_HPP_NO_STD_VECTOR)
590*6fee86a4SJeremy Kemp #include <vector>
591*6fee86a4SJeremy Kemp namespace cl {
592*6fee86a4SJeremy Kemp     template < class T, class Alloc = std::allocator<T> >
593*6fee86a4SJeremy Kemp     using vector = std::vector<T, Alloc>;
594*6fee86a4SJeremy Kemp } // namespace cl
595*6fee86a4SJeremy Kemp #endif // #if !defined(CL_HPP_NO_STD_VECTOR)
596*6fee86a4SJeremy Kemp 
597*6fee86a4SJeremy Kemp #if !defined(CL_HPP_NO_STD_STRING)
598*6fee86a4SJeremy Kemp #include <string>
599*6fee86a4SJeremy Kemp namespace cl {
600*6fee86a4SJeremy Kemp     using string = std::string;
601*6fee86a4SJeremy Kemp } // namespace cl
602*6fee86a4SJeremy Kemp #endif // #if !defined(CL_HPP_NO_STD_STRING)
603*6fee86a4SJeremy Kemp 
604*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 200
605*6fee86a4SJeremy Kemp 
606*6fee86a4SJeremy Kemp #if !defined(CL_HPP_NO_STD_UNIQUE_PTR)
607*6fee86a4SJeremy Kemp #include <memory>
608*6fee86a4SJeremy Kemp namespace cl {
609*6fee86a4SJeremy Kemp     // Replace unique_ptr and allocate_pointer for internal use
610*6fee86a4SJeremy Kemp     // to allow user to replace them
611*6fee86a4SJeremy Kemp     template<class T, class D>
612*6fee86a4SJeremy Kemp     using pointer = std::unique_ptr<T, D>;
613*6fee86a4SJeremy Kemp } // namespace cl
614*6fee86a4SJeremy Kemp #endif
615*6fee86a4SJeremy Kemp #endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 200
616*6fee86a4SJeremy Kemp #if !defined(CL_HPP_NO_STD_ARRAY)
617*6fee86a4SJeremy Kemp #include <array>
618*6fee86a4SJeremy Kemp namespace cl {
619*6fee86a4SJeremy Kemp     template < class T, size_type N >
620*6fee86a4SJeremy Kemp     using array = std::array<T, N>;
621*6fee86a4SJeremy Kemp } // namespace cl
622*6fee86a4SJeremy Kemp #endif // #if !defined(CL_HPP_NO_STD_ARRAY)
623*6fee86a4SJeremy Kemp 
624*6fee86a4SJeremy Kemp // Define size_type appropriately to allow backward-compatibility
625*6fee86a4SJeremy Kemp // use of the old size_t interface class
626*6fee86a4SJeremy Kemp #if defined(CL_HPP_ENABLE_SIZE_T_COMPATIBILITY)
627*6fee86a4SJeremy Kemp namespace cl {
628*6fee86a4SJeremy Kemp     namespace compatibility {
629*6fee86a4SJeremy Kemp         /*! \brief class used to interface between C++ and
630*6fee86a4SJeremy Kemp         *  OpenCL C calls that require arrays of size_t values, whose
631*6fee86a4SJeremy Kemp         *  size is known statically.
632*6fee86a4SJeremy Kemp         */
633*6fee86a4SJeremy Kemp         template <int N>
634*6fee86a4SJeremy Kemp         class size_t
635*6fee86a4SJeremy Kemp         {
636*6fee86a4SJeremy Kemp         private:
637*6fee86a4SJeremy Kemp             size_type data_[N];
638*6fee86a4SJeremy Kemp 
639*6fee86a4SJeremy Kemp         public:
640*6fee86a4SJeremy Kemp             //! \brief Initialize size_t to all 0s
size_t()641*6fee86a4SJeremy Kemp             size_t()
642*6fee86a4SJeremy Kemp             {
643*6fee86a4SJeremy Kemp                 for (int i = 0; i < N; ++i) {
644*6fee86a4SJeremy Kemp                     data_[i] = 0;
645*6fee86a4SJeremy Kemp                 }
646*6fee86a4SJeremy Kemp             }
647*6fee86a4SJeremy Kemp 
size_t(const array<size_type,N> & rhs)648*6fee86a4SJeremy Kemp             size_t(const array<size_type, N> &rhs)
649*6fee86a4SJeremy Kemp             {
650*6fee86a4SJeremy Kemp                 for (int i = 0; i < N; ++i) {
651*6fee86a4SJeremy Kemp                     data_[i] = rhs[i];
652*6fee86a4SJeremy Kemp                 }
653*6fee86a4SJeremy Kemp             }
654*6fee86a4SJeremy Kemp 
operator [](int index)655*6fee86a4SJeremy Kemp             size_type& operator[](int index)
656*6fee86a4SJeremy Kemp             {
657*6fee86a4SJeremy Kemp                 return data_[index];
658*6fee86a4SJeremy Kemp             }
659*6fee86a4SJeremy Kemp 
operator [](int index) const660*6fee86a4SJeremy Kemp             const size_type& operator[](int index) const
661*6fee86a4SJeremy Kemp             {
662*6fee86a4SJeremy Kemp                 return data_[index];
663*6fee86a4SJeremy Kemp             }
664*6fee86a4SJeremy Kemp 
665*6fee86a4SJeremy Kemp             //! \brief Conversion operator to T*.
operator size_type*()666*6fee86a4SJeremy Kemp             operator size_type* ()             { return data_; }
667*6fee86a4SJeremy Kemp 
668*6fee86a4SJeremy Kemp             //! \brief Conversion operator to const T*.
operator const size_type*() const669*6fee86a4SJeremy Kemp             operator const size_type* () const { return data_; }
670*6fee86a4SJeremy Kemp 
operator array<size_type,N>() const671*6fee86a4SJeremy Kemp             operator array<size_type, N>() const
672*6fee86a4SJeremy Kemp             {
673*6fee86a4SJeremy Kemp                 array<size_type, N> ret;
674*6fee86a4SJeremy Kemp 
675*6fee86a4SJeremy Kemp                 for (int i = 0; i < N; ++i) {
676*6fee86a4SJeremy Kemp                     ret[i] = data_[i];
677*6fee86a4SJeremy Kemp                 }
678*6fee86a4SJeremy Kemp                 return ret;
679*6fee86a4SJeremy Kemp             }
680*6fee86a4SJeremy Kemp         };
681*6fee86a4SJeremy Kemp     } // namespace compatibility
682*6fee86a4SJeremy Kemp 
683*6fee86a4SJeremy Kemp     template<int N>
684*6fee86a4SJeremy Kemp     using size_t = compatibility::size_t<N>;
685*6fee86a4SJeremy Kemp } // namespace cl
686*6fee86a4SJeremy Kemp #endif // #if defined(CL_HPP_ENABLE_SIZE_T_COMPATIBILITY)
687*6fee86a4SJeremy Kemp 
688*6fee86a4SJeremy Kemp // Helper alias to avoid confusing the macros
689*6fee86a4SJeremy Kemp namespace cl {
690*6fee86a4SJeremy Kemp     namespace detail {
691*6fee86a4SJeremy Kemp         using size_t_array = array<size_type, 3>;
692*6fee86a4SJeremy Kemp     } // namespace detail
693*6fee86a4SJeremy Kemp } // namespace cl
694*6fee86a4SJeremy Kemp 
695*6fee86a4SJeremy Kemp 
696*6fee86a4SJeremy Kemp /*! \namespace cl
697*6fee86a4SJeremy Kemp  *
698*6fee86a4SJeremy Kemp  * \brief The OpenCL C++ bindings are defined within this namespace.
699*6fee86a4SJeremy Kemp  *
700*6fee86a4SJeremy Kemp  */
701*6fee86a4SJeremy Kemp namespace cl {
702*6fee86a4SJeremy Kemp 
703*6fee86a4SJeremy Kemp #define CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(name) \
704*6fee86a4SJeremy Kemp     using PFN_##name = name##_fn
705*6fee86a4SJeremy Kemp 
706*6fee86a4SJeremy Kemp #define CL_HPP_INIT_CL_EXT_FCN_PTR_(name)                               \
707*6fee86a4SJeremy Kemp     if (!pfn_##name) {                                                  \
708*6fee86a4SJeremy Kemp         pfn_##name = (PFN_##name)clGetExtensionFunctionAddress(#name);  \
709*6fee86a4SJeremy Kemp     }
710*6fee86a4SJeremy Kemp 
711*6fee86a4SJeremy Kemp #define CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, name)            \
712*6fee86a4SJeremy Kemp     if (!pfn_##name) {                                                  \
713*6fee86a4SJeremy Kemp         pfn_##name = (PFN_##name)                                       \
714*6fee86a4SJeremy Kemp             clGetExtensionFunctionAddressForPlatform(platform, #name);  \
715*6fee86a4SJeremy Kemp     }
716*6fee86a4SJeremy Kemp 
717*6fee86a4SJeremy Kemp #ifdef cl_khr_external_memory
718*6fee86a4SJeremy Kemp     enum class ExternalMemoryType : cl_external_memory_handle_type_khr;
719*6fee86a4SJeremy Kemp #endif
720*6fee86a4SJeremy Kemp 
721*6fee86a4SJeremy Kemp     class Memory;
722*6fee86a4SJeremy Kemp     class Platform;
723*6fee86a4SJeremy Kemp     class Program;
724*6fee86a4SJeremy Kemp     class Device;
725*6fee86a4SJeremy Kemp     class Context;
726*6fee86a4SJeremy Kemp     class CommandQueue;
727*6fee86a4SJeremy Kemp     class DeviceCommandQueue;
728*6fee86a4SJeremy Kemp     class Memory;
729*6fee86a4SJeremy Kemp     class Buffer;
730*6fee86a4SJeremy Kemp     class Pipe;
731*6fee86a4SJeremy Kemp #ifdef cl_khr_semaphore
732*6fee86a4SJeremy Kemp     class Semaphore;
733*6fee86a4SJeremy Kemp #endif
734*6fee86a4SJeremy Kemp #if defined(cl_khr_command_buffer)
735*6fee86a4SJeremy Kemp     class CommandBufferKhr;
736*6fee86a4SJeremy Kemp     class MutableCommandKhr;
737*6fee86a4SJeremy Kemp #endif // cl_khr_command_buffer
738*6fee86a4SJeremy Kemp 
739*6fee86a4SJeremy Kemp #if defined(CL_HPP_ENABLE_EXCEPTIONS)
740*6fee86a4SJeremy Kemp     /*! \brief Exception class
741*6fee86a4SJeremy Kemp      *
742*6fee86a4SJeremy Kemp      *  This may be thrown by API functions when CL_HPP_ENABLE_EXCEPTIONS is defined.
743*6fee86a4SJeremy Kemp      */
744*6fee86a4SJeremy Kemp     class Error : public std::exception
745*6fee86a4SJeremy Kemp     {
746*6fee86a4SJeremy Kemp     private:
747*6fee86a4SJeremy Kemp         cl_int err_;
748*6fee86a4SJeremy Kemp         const char * errStr_;
749*6fee86a4SJeremy Kemp     public:
750*6fee86a4SJeremy Kemp         /*! \brief Create a new CL error exception for a given error code
751*6fee86a4SJeremy Kemp          *  and corresponding message.
752*6fee86a4SJeremy Kemp          *
753*6fee86a4SJeremy Kemp          *  \param err error code value.
754*6fee86a4SJeremy Kemp          *
755*6fee86a4SJeremy Kemp          *  \param errStr a descriptive string that must remain in scope until
756*6fee86a4SJeremy Kemp          *                handling of the exception has concluded.  If set, it
757*6fee86a4SJeremy Kemp          *                will be returned by what().
758*6fee86a4SJeremy Kemp          */
Error(cl_int err,const char * errStr=nullptr)759*6fee86a4SJeremy Kemp         Error(cl_int err, const char * errStr = nullptr) : err_(err), errStr_(errStr)
760*6fee86a4SJeremy Kemp         {}
761*6fee86a4SJeremy Kemp 
762*6fee86a4SJeremy Kemp         /*! \brief Get error string associated with exception
763*6fee86a4SJeremy Kemp          *
764*6fee86a4SJeremy Kemp          * \return A memory pointer to the error message string.
765*6fee86a4SJeremy Kemp          */
what() const766*6fee86a4SJeremy Kemp         const char * what() const noexcept override
767*6fee86a4SJeremy Kemp         {
768*6fee86a4SJeremy Kemp             if (errStr_ == nullptr) {
769*6fee86a4SJeremy Kemp                 return "empty";
770*6fee86a4SJeremy Kemp             }
771*6fee86a4SJeremy Kemp             else {
772*6fee86a4SJeremy Kemp                 return errStr_;
773*6fee86a4SJeremy Kemp             }
774*6fee86a4SJeremy Kemp         }
775*6fee86a4SJeremy Kemp 
776*6fee86a4SJeremy Kemp         /*! \brief Get error code associated with exception
777*6fee86a4SJeremy Kemp          *
778*6fee86a4SJeremy Kemp          *  \return The error code.
779*6fee86a4SJeremy Kemp          */
err(void) const780*6fee86a4SJeremy Kemp         cl_int err(void) const { return err_; }
781*6fee86a4SJeremy Kemp     };
782*6fee86a4SJeremy Kemp #define CL_HPP_ERR_STR_(x) #x
783*6fee86a4SJeremy Kemp #else
784*6fee86a4SJeremy Kemp #define CL_HPP_ERR_STR_(x) nullptr
785*6fee86a4SJeremy Kemp #endif // CL_HPP_ENABLE_EXCEPTIONS
786*6fee86a4SJeremy Kemp 
787*6fee86a4SJeremy Kemp 
788*6fee86a4SJeremy Kemp namespace detail
789*6fee86a4SJeremy Kemp {
790*6fee86a4SJeremy Kemp #if defined(CL_HPP_ENABLE_EXCEPTIONS)
errHandler(cl_int err,const char * errStr=nullptr)791*6fee86a4SJeremy Kemp static inline cl_int errHandler (
792*6fee86a4SJeremy Kemp     cl_int err,
793*6fee86a4SJeremy Kemp     const char * errStr = nullptr)
794*6fee86a4SJeremy Kemp {
795*6fee86a4SJeremy Kemp     if (err != CL_SUCCESS) {
796*6fee86a4SJeremy Kemp         throw Error(err, errStr);
797*6fee86a4SJeremy Kemp     }
798*6fee86a4SJeremy Kemp     return err;
799*6fee86a4SJeremy Kemp }
800*6fee86a4SJeremy Kemp #else
801*6fee86a4SJeremy Kemp static inline cl_int errHandler (cl_int err, const char * errStr = nullptr)
802*6fee86a4SJeremy Kemp {
803*6fee86a4SJeremy Kemp     (void) errStr; // suppress unused variable warning
804*6fee86a4SJeremy Kemp     return err;
805*6fee86a4SJeremy Kemp }
806*6fee86a4SJeremy Kemp #endif // CL_HPP_ENABLE_EXCEPTIONS
807*6fee86a4SJeremy Kemp }
808*6fee86a4SJeremy Kemp 
809*6fee86a4SJeremy Kemp 
810*6fee86a4SJeremy Kemp 
811*6fee86a4SJeremy Kemp //! \cond DOXYGEN_DETAIL
812*6fee86a4SJeremy Kemp #if !defined(CL_HPP_USER_OVERRIDE_ERROR_STRINGS)
813*6fee86a4SJeremy Kemp #define __GET_DEVICE_INFO_ERR               CL_HPP_ERR_STR_(clGetDeviceInfo)
814*6fee86a4SJeremy Kemp #define __GET_PLATFORM_INFO_ERR             CL_HPP_ERR_STR_(clGetPlatformInfo)
815*6fee86a4SJeremy Kemp #define __GET_DEVICE_IDS_ERR                CL_HPP_ERR_STR_(clGetDeviceIDs)
816*6fee86a4SJeremy Kemp #define __GET_PLATFORM_IDS_ERR              CL_HPP_ERR_STR_(clGetPlatformIDs)
817*6fee86a4SJeremy Kemp #define __GET_CONTEXT_INFO_ERR              CL_HPP_ERR_STR_(clGetContextInfo)
818*6fee86a4SJeremy Kemp #define __GET_EVENT_INFO_ERR                CL_HPP_ERR_STR_(clGetEventInfo)
819*6fee86a4SJeremy Kemp #define __GET_EVENT_PROFILE_INFO_ERR        CL_HPP_ERR_STR_(clGetEventProfileInfo)
820*6fee86a4SJeremy Kemp #define __GET_MEM_OBJECT_INFO_ERR           CL_HPP_ERR_STR_(clGetMemObjectInfo)
821*6fee86a4SJeremy Kemp #define __GET_IMAGE_INFO_ERR                CL_HPP_ERR_STR_(clGetImageInfo)
822*6fee86a4SJeremy Kemp #define __GET_SAMPLER_INFO_ERR              CL_HPP_ERR_STR_(clGetSamplerInfo)
823*6fee86a4SJeremy Kemp #define __GET_KERNEL_INFO_ERR               CL_HPP_ERR_STR_(clGetKernelInfo)
824*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 120
825*6fee86a4SJeremy Kemp #define __GET_KERNEL_ARG_INFO_ERR           CL_HPP_ERR_STR_(clGetKernelArgInfo)
826*6fee86a4SJeremy Kemp #endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
827*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 210
828*6fee86a4SJeremy Kemp #define __GET_KERNEL_SUB_GROUP_INFO_ERR     CL_HPP_ERR_STR_(clGetKernelSubGroupInfo)
829*6fee86a4SJeremy Kemp #else
830*6fee86a4SJeremy Kemp #define __GET_KERNEL_SUB_GROUP_INFO_ERR     CL_HPP_ERR_STR_(clGetKernelSubGroupInfoKHR)
831*6fee86a4SJeremy Kemp #endif // CL_HPP_TARGET_OPENCL_VERSION >= 210
832*6fee86a4SJeremy Kemp #define __GET_KERNEL_WORK_GROUP_INFO_ERR    CL_HPP_ERR_STR_(clGetKernelWorkGroupInfo)
833*6fee86a4SJeremy Kemp #define __GET_PROGRAM_INFO_ERR              CL_HPP_ERR_STR_(clGetProgramInfo)
834*6fee86a4SJeremy Kemp #define __GET_PROGRAM_BUILD_INFO_ERR        CL_HPP_ERR_STR_(clGetProgramBuildInfo)
835*6fee86a4SJeremy Kemp #define __GET_COMMAND_QUEUE_INFO_ERR        CL_HPP_ERR_STR_(clGetCommandQueueInfo)
836*6fee86a4SJeremy Kemp 
837*6fee86a4SJeremy Kemp #define __CREATE_CONTEXT_ERR                CL_HPP_ERR_STR_(clCreateContext)
838*6fee86a4SJeremy Kemp #define __CREATE_CONTEXT_FROM_TYPE_ERR      CL_HPP_ERR_STR_(clCreateContextFromType)
839*6fee86a4SJeremy Kemp #define __GET_SUPPORTED_IMAGE_FORMATS_ERR   CL_HPP_ERR_STR_(clGetSupportedImageFormats)
840*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 300
841*6fee86a4SJeremy Kemp #define __SET_CONTEXT_DESCTRUCTOR_CALLBACK_ERR  CL_HPP_ERR_STR_(clSetContextDestructorCallback)
842*6fee86a4SJeremy Kemp #endif // CL_HPP_TARGET_OPENCL_VERSION >= 300
843*6fee86a4SJeremy Kemp 
844*6fee86a4SJeremy Kemp #define __CREATE_BUFFER_ERR                 CL_HPP_ERR_STR_(clCreateBuffer)
845*6fee86a4SJeremy Kemp #define __COPY_ERR                          CL_HPP_ERR_STR_(cl::copy)
846*6fee86a4SJeremy Kemp #define __CREATE_SUBBUFFER_ERR              CL_HPP_ERR_STR_(clCreateSubBuffer)
847*6fee86a4SJeremy Kemp #define __CREATE_GL_BUFFER_ERR              CL_HPP_ERR_STR_(clCreateFromGLBuffer)
848*6fee86a4SJeremy Kemp #define __CREATE_GL_RENDER_BUFFER_ERR       CL_HPP_ERR_STR_(clCreateFromGLBuffer)
849*6fee86a4SJeremy Kemp #define __GET_GL_OBJECT_INFO_ERR            CL_HPP_ERR_STR_(clGetGLObjectInfo)
850*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 120
851*6fee86a4SJeremy Kemp #define __CREATE_IMAGE_ERR                  CL_HPP_ERR_STR_(clCreateImage)
852*6fee86a4SJeremy Kemp #define __CREATE_GL_TEXTURE_ERR             CL_HPP_ERR_STR_(clCreateFromGLTexture)
853*6fee86a4SJeremy Kemp #define __IMAGE_DIMENSION_ERR               CL_HPP_ERR_STR_(Incorrect image dimensions)
854*6fee86a4SJeremy Kemp #endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
855*6fee86a4SJeremy Kemp #define __SET_MEM_OBJECT_DESTRUCTOR_CALLBACK_ERR CL_HPP_ERR_STR_(clSetMemObjectDestructorCallback)
856*6fee86a4SJeremy Kemp 
857*6fee86a4SJeremy Kemp #define __CREATE_USER_EVENT_ERR             CL_HPP_ERR_STR_(clCreateUserEvent)
858*6fee86a4SJeremy Kemp #define __SET_USER_EVENT_STATUS_ERR         CL_HPP_ERR_STR_(clSetUserEventStatus)
859*6fee86a4SJeremy Kemp #define __SET_EVENT_CALLBACK_ERR            CL_HPP_ERR_STR_(clSetEventCallback)
860*6fee86a4SJeremy Kemp #define __WAIT_FOR_EVENTS_ERR               CL_HPP_ERR_STR_(clWaitForEvents)
861*6fee86a4SJeremy Kemp 
862*6fee86a4SJeremy Kemp #define __CREATE_KERNEL_ERR                 CL_HPP_ERR_STR_(clCreateKernel)
863*6fee86a4SJeremy Kemp #define __SET_KERNEL_ARGS_ERR               CL_HPP_ERR_STR_(clSetKernelArg)
864*6fee86a4SJeremy Kemp #define __CREATE_PROGRAM_WITH_SOURCE_ERR    CL_HPP_ERR_STR_(clCreateProgramWithSource)
865*6fee86a4SJeremy Kemp #define __CREATE_PROGRAM_WITH_BINARY_ERR    CL_HPP_ERR_STR_(clCreateProgramWithBinary)
866*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 210
867*6fee86a4SJeremy Kemp #define __CREATE_PROGRAM_WITH_IL_ERR        CL_HPP_ERR_STR_(clCreateProgramWithIL)
868*6fee86a4SJeremy Kemp #else
869*6fee86a4SJeremy Kemp #define __CREATE_PROGRAM_WITH_IL_ERR        CL_HPP_ERR_STR_(clCreateProgramWithILKHR)
870*6fee86a4SJeremy Kemp #endif // CL_HPP_TARGET_OPENCL_VERSION >= 210
871*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 120
872*6fee86a4SJeremy Kemp #define __CREATE_PROGRAM_WITH_BUILT_IN_KERNELS_ERR    CL_HPP_ERR_STR_(clCreateProgramWithBuiltInKernels)
873*6fee86a4SJeremy Kemp #endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
874*6fee86a4SJeremy Kemp #define __BUILD_PROGRAM_ERR                 CL_HPP_ERR_STR_(clBuildProgram)
875*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 120
876*6fee86a4SJeremy Kemp #define __COMPILE_PROGRAM_ERR               CL_HPP_ERR_STR_(clCompileProgram)
877*6fee86a4SJeremy Kemp #define __LINK_PROGRAM_ERR                  CL_HPP_ERR_STR_(clLinkProgram)
878*6fee86a4SJeremy Kemp #endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
879*6fee86a4SJeremy Kemp #define __CREATE_KERNELS_IN_PROGRAM_ERR     CL_HPP_ERR_STR_(clCreateKernelsInProgram)
880*6fee86a4SJeremy Kemp 
881*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 200
882*6fee86a4SJeremy Kemp #define __CREATE_COMMAND_QUEUE_WITH_PROPERTIES_ERR          CL_HPP_ERR_STR_(clCreateCommandQueueWithProperties)
883*6fee86a4SJeremy Kemp #define __CREATE_SAMPLER_WITH_PROPERTIES_ERR                CL_HPP_ERR_STR_(clCreateSamplerWithProperties)
884*6fee86a4SJeremy Kemp #endif // CL_HPP_TARGET_OPENCL_VERSION >= 200
885*6fee86a4SJeremy Kemp #define __SET_COMMAND_QUEUE_PROPERTY_ERR    CL_HPP_ERR_STR_(clSetCommandQueueProperty)
886*6fee86a4SJeremy Kemp #define __ENQUEUE_READ_BUFFER_ERR           CL_HPP_ERR_STR_(clEnqueueReadBuffer)
887*6fee86a4SJeremy Kemp #define __ENQUEUE_READ_BUFFER_RECT_ERR      CL_HPP_ERR_STR_(clEnqueueReadBufferRect)
888*6fee86a4SJeremy Kemp #define __ENQUEUE_WRITE_BUFFER_ERR          CL_HPP_ERR_STR_(clEnqueueWriteBuffer)
889*6fee86a4SJeremy Kemp #define __ENQUEUE_WRITE_BUFFER_RECT_ERR     CL_HPP_ERR_STR_(clEnqueueWriteBufferRect)
890*6fee86a4SJeremy Kemp #define __ENQEUE_COPY_BUFFER_ERR            CL_HPP_ERR_STR_(clEnqueueCopyBuffer)
891*6fee86a4SJeremy Kemp #define __ENQEUE_COPY_BUFFER_RECT_ERR       CL_HPP_ERR_STR_(clEnqueueCopyBufferRect)
892*6fee86a4SJeremy Kemp #define __ENQUEUE_FILL_BUFFER_ERR           CL_HPP_ERR_STR_(clEnqueueFillBuffer)
893*6fee86a4SJeremy Kemp #define __ENQUEUE_READ_IMAGE_ERR            CL_HPP_ERR_STR_(clEnqueueReadImage)
894*6fee86a4SJeremy Kemp #define __ENQUEUE_WRITE_IMAGE_ERR           CL_HPP_ERR_STR_(clEnqueueWriteImage)
895*6fee86a4SJeremy Kemp #define __ENQUEUE_COPY_IMAGE_ERR            CL_HPP_ERR_STR_(clEnqueueCopyImage)
896*6fee86a4SJeremy Kemp #define __ENQUEUE_FILL_IMAGE_ERR            CL_HPP_ERR_STR_(clEnqueueFillImage)
897*6fee86a4SJeremy Kemp #define __ENQUEUE_COPY_IMAGE_TO_BUFFER_ERR  CL_HPP_ERR_STR_(clEnqueueCopyImageToBuffer)
898*6fee86a4SJeremy Kemp #define __ENQUEUE_COPY_BUFFER_TO_IMAGE_ERR  CL_HPP_ERR_STR_(clEnqueueCopyBufferToImage)
899*6fee86a4SJeremy Kemp #define __ENQUEUE_MAP_BUFFER_ERR            CL_HPP_ERR_STR_(clEnqueueMapBuffer)
900*6fee86a4SJeremy Kemp #define __ENQUEUE_MAP_SVM_ERR               CL_HPP_ERR_STR_(clEnqueueSVMMap)
901*6fee86a4SJeremy Kemp #define __ENQUEUE_FILL_SVM_ERR              CL_HPP_ERR_STR_(clEnqueueSVMMemFill)
902*6fee86a4SJeremy Kemp #define __ENQUEUE_COPY_SVM_ERR              CL_HPP_ERR_STR_(clEnqueueSVMMemcpy)
903*6fee86a4SJeremy Kemp #define __ENQUEUE_UNMAP_SVM_ERR             CL_HPP_ERR_STR_(clEnqueueSVMUnmap)
904*6fee86a4SJeremy Kemp #define __ENQUEUE_MAP_IMAGE_ERR             CL_HPP_ERR_STR_(clEnqueueMapImage)
905*6fee86a4SJeremy Kemp #define __ENQUEUE_UNMAP_MEM_OBJECT_ERR      CL_HPP_ERR_STR_(clEnqueueUnMapMemObject)
906*6fee86a4SJeremy Kemp #define __ENQUEUE_NDRANGE_KERNEL_ERR        CL_HPP_ERR_STR_(clEnqueueNDRangeKernel)
907*6fee86a4SJeremy Kemp #define __ENQUEUE_NATIVE_KERNEL             CL_HPP_ERR_STR_(clEnqueueNativeKernel)
908*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 120
909*6fee86a4SJeremy Kemp #define __ENQUEUE_MIGRATE_MEM_OBJECTS_ERR   CL_HPP_ERR_STR_(clEnqueueMigrateMemObjects)
910*6fee86a4SJeremy Kemp #endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
911*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 210
912*6fee86a4SJeremy Kemp #define __ENQUEUE_MIGRATE_SVM_ERR   CL_HPP_ERR_STR_(clEnqueueSVMMigrateMem)
913*6fee86a4SJeremy Kemp #define __SET_DEFAULT_DEVICE_COMMAND_QUEUE_ERR   CL_HPP_ERR_STR_(clSetDefaultDeviceCommandQueue)
914*6fee86a4SJeremy Kemp #endif // CL_HPP_TARGET_OPENCL_VERSION >= 210
915*6fee86a4SJeremy Kemp 
916*6fee86a4SJeremy Kemp 
917*6fee86a4SJeremy Kemp #define __ENQUEUE_ACQUIRE_GL_ERR            CL_HPP_ERR_STR_(clEnqueueAcquireGLObjects)
918*6fee86a4SJeremy Kemp #define __ENQUEUE_RELEASE_GL_ERR            CL_HPP_ERR_STR_(clEnqueueReleaseGLObjects)
919*6fee86a4SJeremy Kemp 
920*6fee86a4SJeremy Kemp #define __CREATE_PIPE_ERR             CL_HPP_ERR_STR_(clCreatePipe)
921*6fee86a4SJeremy Kemp #define __GET_PIPE_INFO_ERR           CL_HPP_ERR_STR_(clGetPipeInfo)
922*6fee86a4SJeremy Kemp 
923*6fee86a4SJeremy Kemp #define __RETAIN_ERR                        CL_HPP_ERR_STR_(Retain Object)
924*6fee86a4SJeremy Kemp #define __RELEASE_ERR                       CL_HPP_ERR_STR_(Release Object)
925*6fee86a4SJeremy Kemp #define __FLUSH_ERR                         CL_HPP_ERR_STR_(clFlush)
926*6fee86a4SJeremy Kemp #define __FINISH_ERR                        CL_HPP_ERR_STR_(clFinish)
927*6fee86a4SJeremy Kemp #define __VECTOR_CAPACITY_ERR               CL_HPP_ERR_STR_(Vector capacity error)
928*6fee86a4SJeremy Kemp 
929*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 210
930*6fee86a4SJeremy Kemp #define __GET_HOST_TIMER_ERR           CL_HPP_ERR_STR_(clGetHostTimer)
931*6fee86a4SJeremy Kemp #define __GET_DEVICE_AND_HOST_TIMER_ERR           CL_HPP_ERR_STR_(clGetDeviceAndHostTimer)
932*6fee86a4SJeremy Kemp #endif
933*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 220
934*6fee86a4SJeremy Kemp #define __SET_PROGRAM_RELEASE_CALLBACK_ERR          CL_HPP_ERR_STR_(clSetProgramReleaseCallback)
935*6fee86a4SJeremy Kemp #define __SET_PROGRAM_SPECIALIZATION_CONSTANT_ERR   CL_HPP_ERR_STR_(clSetProgramSpecializationConstant)
936*6fee86a4SJeremy Kemp #endif
937*6fee86a4SJeremy Kemp 
938*6fee86a4SJeremy Kemp #ifdef cl_khr_external_memory
939*6fee86a4SJeremy Kemp #define __ENQUEUE_ACQUIRE_EXTERNAL_MEMORY_ERR       CL_HPP_ERR_STR_(clEnqueueAcquireExternalMemObjectsKHR)
940*6fee86a4SJeremy Kemp #define __ENQUEUE_RELEASE_EXTERNAL_MEMORY_ERR       CL_HPP_ERR_STR_(clEnqueueReleaseExternalMemObjectsKHR)
941*6fee86a4SJeremy Kemp #endif
942*6fee86a4SJeremy Kemp 
943*6fee86a4SJeremy Kemp #ifdef cl_khr_semaphore
944*6fee86a4SJeremy Kemp #define __GET_SEMAPHORE_KHR_INFO_ERR                CL_HPP_ERR_STR_(clGetSemaphoreInfoKHR)
945*6fee86a4SJeremy Kemp #define __CREATE_SEMAPHORE_KHR_WITH_PROPERTIES_ERR  CL_HPP_ERR_STR_(clCreateSemaphoreWithPropertiesKHR)
946*6fee86a4SJeremy Kemp #define __ENQUEUE_WAIT_SEMAPHORE_KHR_ERR            CL_HPP_ERR_STR_(clEnqueueWaitSemaphoresKHR)
947*6fee86a4SJeremy Kemp #define __ENQUEUE_SIGNAL_SEMAPHORE_KHR_ERR          CL_HPP_ERR_STR_(clEnqueueSignalSemaphoresKHR)
948*6fee86a4SJeremy Kemp #define __RETAIN_SEMAPHORE_KHR_ERR                  CL_HPP_ERR_STR_(clRetainSemaphoreKHR)
949*6fee86a4SJeremy Kemp #define __RELEASE_SEMAPHORE_KHR_ERR                 CL_HPP_ERR_STR_(clReleaseSemaphoreKHR)
950*6fee86a4SJeremy Kemp #endif
951*6fee86a4SJeremy Kemp 
952*6fee86a4SJeremy Kemp #ifdef cl_khr_external_semaphore
953*6fee86a4SJeremy Kemp #define __GET_SEMAPHORE_HANDLE_FOR_TYPE_KHR_ERR         CL_HPP_ERR_STR_(clGetSemaphoreHandleForTypeKHR)
954*6fee86a4SJeremy Kemp #endif // cl_khr_external_semaphore
955*6fee86a4SJeremy Kemp 
956*6fee86a4SJeremy Kemp #if defined(cl_khr_command_buffer)
957*6fee86a4SJeremy Kemp #define __CREATE_COMMAND_BUFFER_KHR_ERR             CL_HPP_ERR_STR_(clCreateCommandBufferKHR)
958*6fee86a4SJeremy Kemp #define __GET_COMMAND_BUFFER_INFO_KHR_ERR           CL_HPP_ERR_STR_(clGetCommandBufferInfoKHR)
959*6fee86a4SJeremy Kemp #define __FINALIZE_COMMAND_BUFFER_KHR_ERR           CL_HPP_ERR_STR_(clFinalizeCommandBufferKHR)
960*6fee86a4SJeremy Kemp #define __ENQUEUE_COMMAND_BUFFER_KHR_ERR            CL_HPP_ERR_STR_(clEnqueueCommandBufferKHR)
961*6fee86a4SJeremy Kemp #define __COMMAND_BARRIER_WITH_WAIT_LIST_KHR_ERR    CL_HPP_ERR_STR_(clCommandBarrierWithWaitListKHR)
962*6fee86a4SJeremy Kemp #define __COMMAND_COPY_BUFFER_KHR_ERR               CL_HPP_ERR_STR_(clCommandCopyBufferKHR)
963*6fee86a4SJeremy Kemp #define __COMMAND_COPY_BUFFER_RECT_KHR_ERR          CL_HPP_ERR_STR_(clCommandCopyBufferRectKHR)
964*6fee86a4SJeremy Kemp #define __COMMAND_COPY_BUFFER_TO_IMAGE_KHR_ERR      CL_HPP_ERR_STR_(clCommandCopyBufferToImageKHR)
965*6fee86a4SJeremy Kemp #define __COMMAND_COPY_IMAGE_KHR_ERR                CL_HPP_ERR_STR_(clCommandCopyImageKHR)
966*6fee86a4SJeremy Kemp #define __COMMAND_COPY_IMAGE_TO_BUFFER_KHR_ERR      CL_HPP_ERR_STR_(clCommandCopyImageToBufferKHR)
967*6fee86a4SJeremy Kemp #define __COMMAND_FILL_BUFFER_KHR_ERR               CL_HPP_ERR_STR_(clCommandFillBufferKHR)
968*6fee86a4SJeremy Kemp #define __COMMAND_FILL_IMAGE_KHR_ERR                CL_HPP_ERR_STR_(clCommandFillImageKHR)
969*6fee86a4SJeremy Kemp #define __COMMAND_NDRANGE_KERNEL_KHR_ERR            CL_HPP_ERR_STR_(clCommandNDRangeKernelKHR)
970*6fee86a4SJeremy Kemp #define __UPDATE_MUTABLE_COMMANDS_KHR_ERR           CL_HPP_ERR_STR_(clUpdateMutableCommandsKHR)
971*6fee86a4SJeremy Kemp #define __GET_MUTABLE_COMMAND_INFO_KHR_ERR          CL_HPP_ERR_STR_(clGetMutableCommandInfoKHR)
972*6fee86a4SJeremy Kemp #define __RETAIN_COMMAND_BUFFER_KHR_ERR             CL_HPP_ERR_STR_(clRetainCommandBufferKHR)
973*6fee86a4SJeremy Kemp #define __RELEASE_COMMAND_BUFFER_KHR_ERR            CL_HPP_ERR_STR_(clReleaseCommandBufferKHR)
974*6fee86a4SJeremy Kemp #endif // cl_khr_command_buffer
975*6fee86a4SJeremy Kemp 
976*6fee86a4SJeremy Kemp #if defined(cl_ext_image_requirements_info)
977*6fee86a4SJeremy Kemp #define __GET_IMAGE_REQUIREMENT_INFO_EXT_ERR            CL_HPP_ERR_STR_(clGetImageRequirementsInfoEXT)
978*6fee86a4SJeremy Kemp #endif //cl_ext_image_requirements_info
979*6fee86a4SJeremy Kemp 
980*6fee86a4SJeremy Kemp /**
981*6fee86a4SJeremy Kemp  * CL 1.2 version that uses device fission.
982*6fee86a4SJeremy Kemp  */
983*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 120
984*6fee86a4SJeremy Kemp #define __CREATE_SUB_DEVICES_ERR            CL_HPP_ERR_STR_(clCreateSubDevices)
985*6fee86a4SJeremy Kemp #else
986*6fee86a4SJeremy Kemp #define __CREATE_SUB_DEVICES_ERR            CL_HPP_ERR_STR_(clCreateSubDevicesEXT)
987*6fee86a4SJeremy Kemp #endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
988*6fee86a4SJeremy Kemp 
989*6fee86a4SJeremy Kemp /**
990*6fee86a4SJeremy Kemp  * Deprecated APIs for 1.2
991*6fee86a4SJeremy Kemp  */
992*6fee86a4SJeremy Kemp #if defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS)
993*6fee86a4SJeremy Kemp #define __ENQUEUE_MARKER_ERR                CL_HPP_ERR_STR_(clEnqueueMarker)
994*6fee86a4SJeremy Kemp #define __ENQUEUE_WAIT_FOR_EVENTS_ERR       CL_HPP_ERR_STR_(clEnqueueWaitForEvents)
995*6fee86a4SJeremy Kemp #define __ENQUEUE_BARRIER_ERR               CL_HPP_ERR_STR_(clEnqueueBarrier)
996*6fee86a4SJeremy Kemp #define __UNLOAD_COMPILER_ERR               CL_HPP_ERR_STR_(clUnloadCompiler)
997*6fee86a4SJeremy Kemp #define __CREATE_GL_TEXTURE_2D_ERR          CL_HPP_ERR_STR_(clCreateFromGLTexture2D)
998*6fee86a4SJeremy Kemp #define __CREATE_GL_TEXTURE_3D_ERR          CL_HPP_ERR_STR_(clCreateFromGLTexture3D)
999*6fee86a4SJeremy Kemp #define __CREATE_IMAGE2D_ERR                CL_HPP_ERR_STR_(clCreateImage2D)
1000*6fee86a4SJeremy Kemp #define __CREATE_IMAGE3D_ERR                CL_HPP_ERR_STR_(clCreateImage3D)
1001*6fee86a4SJeremy Kemp #endif // #if defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS)
1002*6fee86a4SJeremy Kemp 
1003*6fee86a4SJeremy Kemp /**
1004*6fee86a4SJeremy Kemp  * Deprecated APIs for 2.0
1005*6fee86a4SJeremy Kemp  */
1006*6fee86a4SJeremy Kemp #if defined(CL_USE_DEPRECATED_OPENCL_1_2_APIS)
1007*6fee86a4SJeremy Kemp #define __CREATE_COMMAND_QUEUE_ERR          CL_HPP_ERR_STR_(clCreateCommandQueue)
1008*6fee86a4SJeremy Kemp #define __ENQUEUE_TASK_ERR                  CL_HPP_ERR_STR_(clEnqueueTask)
1009*6fee86a4SJeremy Kemp #define __CREATE_SAMPLER_ERR                CL_HPP_ERR_STR_(clCreateSampler)
1010*6fee86a4SJeremy Kemp #endif // #if defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS)
1011*6fee86a4SJeremy Kemp 
1012*6fee86a4SJeremy Kemp /**
1013*6fee86a4SJeremy Kemp  * CL 1.2 marker and barrier commands
1014*6fee86a4SJeremy Kemp  */
1015*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 120
1016*6fee86a4SJeremy Kemp #define __ENQUEUE_MARKER_WAIT_LIST_ERR                CL_HPP_ERR_STR_(clEnqueueMarkerWithWaitList)
1017*6fee86a4SJeremy Kemp #define __ENQUEUE_BARRIER_WAIT_LIST_ERR               CL_HPP_ERR_STR_(clEnqueueBarrierWithWaitList)
1018*6fee86a4SJeremy Kemp #endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
1019*6fee86a4SJeremy Kemp 
1020*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 210
1021*6fee86a4SJeremy Kemp #define __CLONE_KERNEL_ERR     CL_HPP_ERR_STR_(clCloneKernel)
1022*6fee86a4SJeremy Kemp #endif // CL_HPP_TARGET_OPENCL_VERSION >= 210
1023*6fee86a4SJeremy Kemp 
1024*6fee86a4SJeremy Kemp #endif // CL_HPP_USER_OVERRIDE_ERROR_STRINGS
1025*6fee86a4SJeremy Kemp //! \endcond
1026*6fee86a4SJeremy Kemp 
1027*6fee86a4SJeremy Kemp #ifdef cl_khr_external_memory
1028*6fee86a4SJeremy Kemp CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clEnqueueAcquireExternalMemObjectsKHR);
1029*6fee86a4SJeremy Kemp CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clEnqueueReleaseExternalMemObjectsKHR);
1030*6fee86a4SJeremy Kemp 
1031*6fee86a4SJeremy Kemp CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clEnqueueAcquireExternalMemObjectsKHR pfn_clEnqueueAcquireExternalMemObjectsKHR = nullptr;
1032*6fee86a4SJeremy Kemp CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clEnqueueReleaseExternalMemObjectsKHR pfn_clEnqueueReleaseExternalMemObjectsKHR = nullptr;
1033*6fee86a4SJeremy Kemp #endif // cl_khr_external_memory
1034*6fee86a4SJeremy Kemp 
1035*6fee86a4SJeremy Kemp #ifdef cl_khr_semaphore
1036*6fee86a4SJeremy Kemp CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clCreateSemaphoreWithPropertiesKHR);
1037*6fee86a4SJeremy Kemp CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clReleaseSemaphoreKHR);
1038*6fee86a4SJeremy Kemp CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clRetainSemaphoreKHR);
1039*6fee86a4SJeremy Kemp CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clEnqueueWaitSemaphoresKHR);
1040*6fee86a4SJeremy Kemp CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clEnqueueSignalSemaphoresKHR);
1041*6fee86a4SJeremy Kemp CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clGetSemaphoreInfoKHR);
1042*6fee86a4SJeremy Kemp 
1043*6fee86a4SJeremy Kemp CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clCreateSemaphoreWithPropertiesKHR pfn_clCreateSemaphoreWithPropertiesKHR  = nullptr;
1044*6fee86a4SJeremy Kemp CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clReleaseSemaphoreKHR              pfn_clReleaseSemaphoreKHR               = nullptr;
1045*6fee86a4SJeremy Kemp CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clRetainSemaphoreKHR               pfn_clRetainSemaphoreKHR                = nullptr;
1046*6fee86a4SJeremy Kemp CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clEnqueueWaitSemaphoresKHR         pfn_clEnqueueWaitSemaphoresKHR          = nullptr;
1047*6fee86a4SJeremy Kemp CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clEnqueueSignalSemaphoresKHR       pfn_clEnqueueSignalSemaphoresKHR        = nullptr;
1048*6fee86a4SJeremy Kemp CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clGetSemaphoreInfoKHR              pfn_clGetSemaphoreInfoKHR               = nullptr;
1049*6fee86a4SJeremy Kemp #endif // cl_khr_semaphore
1050*6fee86a4SJeremy Kemp 
1051*6fee86a4SJeremy Kemp #ifdef cl_khr_external_semaphore
1052*6fee86a4SJeremy Kemp CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clGetSemaphoreHandleForTypeKHR);
1053*6fee86a4SJeremy Kemp CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clGetSemaphoreHandleForTypeKHR     pfn_clGetSemaphoreHandleForTypeKHR      = nullptr;
1054*6fee86a4SJeremy Kemp #endif // cl_khr_external_semaphore
1055*6fee86a4SJeremy Kemp 
1056*6fee86a4SJeremy Kemp #if defined(cl_khr_command_buffer)
1057*6fee86a4SJeremy Kemp CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clCreateCommandBufferKHR);
1058*6fee86a4SJeremy Kemp CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clFinalizeCommandBufferKHR);
1059*6fee86a4SJeremy Kemp CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clRetainCommandBufferKHR);
1060*6fee86a4SJeremy Kemp CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clReleaseCommandBufferKHR);
1061*6fee86a4SJeremy Kemp CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clGetCommandBufferInfoKHR);
1062*6fee86a4SJeremy Kemp CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clEnqueueCommandBufferKHR);
1063*6fee86a4SJeremy Kemp CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clCommandBarrierWithWaitListKHR);
1064*6fee86a4SJeremy Kemp CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clCommandCopyBufferKHR);
1065*6fee86a4SJeremy Kemp CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clCommandCopyBufferRectKHR);
1066*6fee86a4SJeremy Kemp CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clCommandCopyBufferToImageKHR);
1067*6fee86a4SJeremy Kemp CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clCommandCopyImageKHR);
1068*6fee86a4SJeremy Kemp CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clCommandCopyImageToBufferKHR);
1069*6fee86a4SJeremy Kemp CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clCommandFillBufferKHR);
1070*6fee86a4SJeremy Kemp CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clCommandFillImageKHR);
1071*6fee86a4SJeremy Kemp CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clCommandNDRangeKernelKHR);
1072*6fee86a4SJeremy Kemp 
1073*6fee86a4SJeremy Kemp CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clCreateCommandBufferKHR pfn_clCreateCommandBufferKHR               = nullptr;
1074*6fee86a4SJeremy Kemp CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clFinalizeCommandBufferKHR pfn_clFinalizeCommandBufferKHR           = nullptr;
1075*6fee86a4SJeremy Kemp CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clRetainCommandBufferKHR pfn_clRetainCommandBufferKHR               = nullptr;
1076*6fee86a4SJeremy Kemp CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clReleaseCommandBufferKHR pfn_clReleaseCommandBufferKHR             = nullptr;
1077*6fee86a4SJeremy Kemp CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clGetCommandBufferInfoKHR pfn_clGetCommandBufferInfoKHR             = nullptr;
1078*6fee86a4SJeremy Kemp CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clEnqueueCommandBufferKHR pfn_clEnqueueCommandBufferKHR             = nullptr;
1079*6fee86a4SJeremy Kemp CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clCommandBarrierWithWaitListKHR pfn_clCommandBarrierWithWaitListKHR = nullptr;
1080*6fee86a4SJeremy Kemp CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clCommandCopyBufferKHR pfn_clCommandCopyBufferKHR                   = nullptr;
1081*6fee86a4SJeremy Kemp CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clCommandCopyBufferRectKHR pfn_clCommandCopyBufferRectKHR           = nullptr;
1082*6fee86a4SJeremy Kemp CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clCommandCopyBufferToImageKHR pfn_clCommandCopyBufferToImageKHR     = nullptr;
1083*6fee86a4SJeremy Kemp CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clCommandCopyImageKHR pfn_clCommandCopyImageKHR                     = nullptr;
1084*6fee86a4SJeremy Kemp CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clCommandCopyImageToBufferKHR pfn_clCommandCopyImageToBufferKHR     = nullptr;
1085*6fee86a4SJeremy Kemp CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clCommandFillBufferKHR pfn_clCommandFillBufferKHR                   = nullptr;
1086*6fee86a4SJeremy Kemp CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clCommandFillImageKHR pfn_clCommandFillImageKHR                     = nullptr;
1087*6fee86a4SJeremy Kemp CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clCommandNDRangeKernelKHR pfn_clCommandNDRangeKernelKHR             = nullptr;
1088*6fee86a4SJeremy Kemp #endif /* cl_khr_command_buffer */
1089*6fee86a4SJeremy Kemp 
1090*6fee86a4SJeremy Kemp #if defined(cl_khr_command_buffer_mutable_dispatch)
1091*6fee86a4SJeremy Kemp CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clUpdateMutableCommandsKHR);
1092*6fee86a4SJeremy Kemp CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clGetMutableCommandInfoKHR);
1093*6fee86a4SJeremy Kemp 
1094*6fee86a4SJeremy Kemp CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clUpdateMutableCommandsKHR pfn_clUpdateMutableCommandsKHR           = nullptr;
1095*6fee86a4SJeremy Kemp CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clGetMutableCommandInfoKHR pfn_clGetMutableCommandInfoKHR           = nullptr;
1096*6fee86a4SJeremy Kemp #endif /* cl_khr_command_buffer_mutable_dispatch */
1097*6fee86a4SJeremy Kemp 
1098*6fee86a4SJeremy Kemp #if defined(cl_ext_image_requirements_info)
1099*6fee86a4SJeremy Kemp CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clGetImageRequirementsInfoEXT);
1100*6fee86a4SJeremy Kemp CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clGetImageRequirementsInfoEXT pfn_clGetImageRequirementsInfoEXT  = nullptr;
1101*6fee86a4SJeremy Kemp #endif
1102*6fee86a4SJeremy Kemp 
1103*6fee86a4SJeremy Kemp #if defined(cl_ext_device_fission)
1104*6fee86a4SJeremy Kemp CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_(clCreateSubDevicesEXT);
1105*6fee86a4SJeremy Kemp CL_HPP_DEFINE_STATIC_MEMBER_ PFN_clCreateSubDevicesEXT
1106*6fee86a4SJeremy Kemp     pfn_clCreateSubDevicesEXT = nullptr;
1107*6fee86a4SJeremy Kemp #endif
1108*6fee86a4SJeremy Kemp 
1109*6fee86a4SJeremy Kemp namespace detail {
1110*6fee86a4SJeremy Kemp 
1111*6fee86a4SJeremy Kemp // Generic getInfoHelper. The final parameter is used to guide overload
1112*6fee86a4SJeremy Kemp // resolution: the actual parameter passed is an int, which makes this
1113*6fee86a4SJeremy Kemp // a worse conversion sequence than a specialization that declares the
1114*6fee86a4SJeremy Kemp // parameter as an int.
1115*6fee86a4SJeremy Kemp template<typename Functor, typename T>
getInfoHelper(Functor f,cl_uint name,T * param,long)1116*6fee86a4SJeremy Kemp inline cl_int getInfoHelper(Functor f, cl_uint name, T* param, long)
1117*6fee86a4SJeremy Kemp {
1118*6fee86a4SJeremy Kemp     return f(name, sizeof(T), param, nullptr);
1119*6fee86a4SJeremy Kemp }
1120*6fee86a4SJeremy Kemp 
1121*6fee86a4SJeremy Kemp // Specialized for getInfo<CL_PROGRAM_BINARIES>
1122*6fee86a4SJeremy Kemp // Assumes that the output vector was correctly resized on the way in
1123*6fee86a4SJeremy Kemp template <typename Func>
getInfoHelper(Func f,cl_uint name,vector<vector<unsigned char>> * param,int)1124*6fee86a4SJeremy Kemp inline cl_int getInfoHelper(Func f, cl_uint name, vector<vector<unsigned char>>* param, int)
1125*6fee86a4SJeremy Kemp {
1126*6fee86a4SJeremy Kemp     if (name != CL_PROGRAM_BINARIES) {
1127*6fee86a4SJeremy Kemp         return CL_INVALID_VALUE;
1128*6fee86a4SJeremy Kemp     }
1129*6fee86a4SJeremy Kemp     if (param) {
1130*6fee86a4SJeremy Kemp         // Create array of pointers, calculate total size and pass pointer array in
1131*6fee86a4SJeremy Kemp         size_type numBinaries = param->size();
1132*6fee86a4SJeremy Kemp         vector<unsigned char*> binariesPointers(numBinaries);
1133*6fee86a4SJeremy Kemp 
1134*6fee86a4SJeremy Kemp         for (size_type i = 0; i < numBinaries; ++i)
1135*6fee86a4SJeremy Kemp         {
1136*6fee86a4SJeremy Kemp             binariesPointers[i] = (*param)[i].data();
1137*6fee86a4SJeremy Kemp         }
1138*6fee86a4SJeremy Kemp 
1139*6fee86a4SJeremy Kemp         cl_int err = f(name, numBinaries * sizeof(unsigned char*), binariesPointers.data(), nullptr);
1140*6fee86a4SJeremy Kemp 
1141*6fee86a4SJeremy Kemp         if (err != CL_SUCCESS) {
1142*6fee86a4SJeremy Kemp             return err;
1143*6fee86a4SJeremy Kemp         }
1144*6fee86a4SJeremy Kemp     }
1145*6fee86a4SJeremy Kemp 
1146*6fee86a4SJeremy Kemp 
1147*6fee86a4SJeremy Kemp     return CL_SUCCESS;
1148*6fee86a4SJeremy Kemp }
1149*6fee86a4SJeremy Kemp 
1150*6fee86a4SJeremy Kemp // Specialized getInfoHelper for vector params
1151*6fee86a4SJeremy Kemp template <typename Func, typename T>
getInfoHelper(Func f,cl_uint name,vector<T> * param,long)1152*6fee86a4SJeremy Kemp inline cl_int getInfoHelper(Func f, cl_uint name, vector<T>* param, long)
1153*6fee86a4SJeremy Kemp {
1154*6fee86a4SJeremy Kemp     size_type required;
1155*6fee86a4SJeremy Kemp     cl_int err = f(name, 0, nullptr, &required);
1156*6fee86a4SJeremy Kemp     if (err != CL_SUCCESS) {
1157*6fee86a4SJeremy Kemp         return err;
1158*6fee86a4SJeremy Kemp     }
1159*6fee86a4SJeremy Kemp     const size_type elements = required / sizeof(T);
1160*6fee86a4SJeremy Kemp 
1161*6fee86a4SJeremy Kemp     // Temporary to avoid changing param on an error
1162*6fee86a4SJeremy Kemp     vector<T> localData(elements);
1163*6fee86a4SJeremy Kemp     err = f(name, required, localData.data(), nullptr);
1164*6fee86a4SJeremy Kemp     if (err != CL_SUCCESS) {
1165*6fee86a4SJeremy Kemp         return err;
1166*6fee86a4SJeremy Kemp     }
1167*6fee86a4SJeremy Kemp     if (param) {
1168*6fee86a4SJeremy Kemp         *param = std::move(localData);
1169*6fee86a4SJeremy Kemp     }
1170*6fee86a4SJeremy Kemp 
1171*6fee86a4SJeremy Kemp     return CL_SUCCESS;
1172*6fee86a4SJeremy Kemp }
1173*6fee86a4SJeremy Kemp 
1174*6fee86a4SJeremy Kemp /* Specialization for reference-counted types. This depends on the
1175*6fee86a4SJeremy Kemp  * existence of Wrapper<T>::cl_type, and none of the other types having the
1176*6fee86a4SJeremy Kemp  * cl_type member. Note that simplify specifying the parameter as Wrapper<T>
1177*6fee86a4SJeremy Kemp  * does not work, because when using a derived type (e.g. Context) the generic
1178*6fee86a4SJeremy Kemp  * template will provide a better match.
1179*6fee86a4SJeremy Kemp  */
1180*6fee86a4SJeremy Kemp template <typename Func, typename T>
getInfoHelper(Func f,cl_uint name,vector<T> * param,int,typename T::cl_type=0)1181*6fee86a4SJeremy Kemp inline cl_int getInfoHelper(
1182*6fee86a4SJeremy Kemp     Func f, cl_uint name, vector<T>* param, int, typename T::cl_type = 0)
1183*6fee86a4SJeremy Kemp {
1184*6fee86a4SJeremy Kemp     size_type required;
1185*6fee86a4SJeremy Kemp     cl_int err = f(name, 0, nullptr, &required);
1186*6fee86a4SJeremy Kemp     if (err != CL_SUCCESS) {
1187*6fee86a4SJeremy Kemp         return err;
1188*6fee86a4SJeremy Kemp     }
1189*6fee86a4SJeremy Kemp 
1190*6fee86a4SJeremy Kemp     const size_type elements = required / sizeof(typename T::cl_type);
1191*6fee86a4SJeremy Kemp 
1192*6fee86a4SJeremy Kemp     vector<typename T::cl_type> value(elements);
1193*6fee86a4SJeremy Kemp     err = f(name, required, value.data(), nullptr);
1194*6fee86a4SJeremy Kemp     if (err != CL_SUCCESS) {
1195*6fee86a4SJeremy Kemp         return err;
1196*6fee86a4SJeremy Kemp     }
1197*6fee86a4SJeremy Kemp 
1198*6fee86a4SJeremy Kemp     if (param) {
1199*6fee86a4SJeremy Kemp         // Assign to convert CL type to T for each element
1200*6fee86a4SJeremy Kemp         param->resize(elements);
1201*6fee86a4SJeremy Kemp 
1202*6fee86a4SJeremy Kemp         // Assign to param, constructing with retain behaviour
1203*6fee86a4SJeremy Kemp         // to correctly capture each underlying CL object
1204*6fee86a4SJeremy Kemp         for (size_type i = 0; i < elements; i++) {
1205*6fee86a4SJeremy Kemp             (*param)[i] = T(value[i], true);
1206*6fee86a4SJeremy Kemp         }
1207*6fee86a4SJeremy Kemp     }
1208*6fee86a4SJeremy Kemp     return CL_SUCCESS;
1209*6fee86a4SJeremy Kemp }
1210*6fee86a4SJeremy Kemp 
1211*6fee86a4SJeremy Kemp // Specialized GetInfoHelper for string params
1212*6fee86a4SJeremy Kemp template <typename Func>
getInfoHelper(Func f,cl_uint name,string * param,long)1213*6fee86a4SJeremy Kemp inline cl_int getInfoHelper(Func f, cl_uint name, string* param, long)
1214*6fee86a4SJeremy Kemp {
1215*6fee86a4SJeremy Kemp     size_type required;
1216*6fee86a4SJeremy Kemp     cl_int err = f(name, 0, nullptr, &required);
1217*6fee86a4SJeremy Kemp     if (err != CL_SUCCESS) {
1218*6fee86a4SJeremy Kemp         return err;
1219*6fee86a4SJeremy Kemp     }
1220*6fee86a4SJeremy Kemp 
1221*6fee86a4SJeremy Kemp     // std::string has a constant data member
1222*6fee86a4SJeremy Kemp     // a char vector does not
1223*6fee86a4SJeremy Kemp     if (required > 0) {
1224*6fee86a4SJeremy Kemp         vector<char> value(required);
1225*6fee86a4SJeremy Kemp         err = f(name, required, value.data(), nullptr);
1226*6fee86a4SJeremy Kemp         if (err != CL_SUCCESS) {
1227*6fee86a4SJeremy Kemp             return err;
1228*6fee86a4SJeremy Kemp         }
1229*6fee86a4SJeremy Kemp         if (param) {
1230*6fee86a4SJeremy Kemp             param->assign(value.begin(), value.end() - 1);
1231*6fee86a4SJeremy Kemp         }
1232*6fee86a4SJeremy Kemp     }
1233*6fee86a4SJeremy Kemp     else if (param) {
1234*6fee86a4SJeremy Kemp         param->assign("");
1235*6fee86a4SJeremy Kemp     }
1236*6fee86a4SJeremy Kemp     return CL_SUCCESS;
1237*6fee86a4SJeremy Kemp }
1238*6fee86a4SJeremy Kemp 
1239*6fee86a4SJeremy Kemp // Specialized GetInfoHelper for clsize_t params
1240*6fee86a4SJeremy Kemp template <typename Func, size_type N>
getInfoHelper(Func f,cl_uint name,array<size_type,N> * param,long)1241*6fee86a4SJeremy Kemp inline cl_int getInfoHelper(Func f, cl_uint name, array<size_type, N>* param, long)
1242*6fee86a4SJeremy Kemp {
1243*6fee86a4SJeremy Kemp     size_type required;
1244*6fee86a4SJeremy Kemp     cl_int err = f(name, 0, nullptr, &required);
1245*6fee86a4SJeremy Kemp     if (err != CL_SUCCESS) {
1246*6fee86a4SJeremy Kemp         return err;
1247*6fee86a4SJeremy Kemp     }
1248*6fee86a4SJeremy Kemp 
1249*6fee86a4SJeremy Kemp     size_type elements = required / sizeof(size_type);
1250*6fee86a4SJeremy Kemp     vector<size_type> value(elements, 0);
1251*6fee86a4SJeremy Kemp 
1252*6fee86a4SJeremy Kemp     err = f(name, required, value.data(), nullptr);
1253*6fee86a4SJeremy Kemp     if (err != CL_SUCCESS) {
1254*6fee86a4SJeremy Kemp         return err;
1255*6fee86a4SJeremy Kemp     }
1256*6fee86a4SJeremy Kemp 
1257*6fee86a4SJeremy Kemp     // Bound the copy with N to prevent overruns
1258*6fee86a4SJeremy Kemp     // if passed N > than the amount copied
1259*6fee86a4SJeremy Kemp     if (elements > N) {
1260*6fee86a4SJeremy Kemp         elements = N;
1261*6fee86a4SJeremy Kemp     }
1262*6fee86a4SJeremy Kemp     for (size_type i = 0; i < elements; ++i) {
1263*6fee86a4SJeremy Kemp         (*param)[i] = value[i];
1264*6fee86a4SJeremy Kemp     }
1265*6fee86a4SJeremy Kemp 
1266*6fee86a4SJeremy Kemp     return CL_SUCCESS;
1267*6fee86a4SJeremy Kemp }
1268*6fee86a4SJeremy Kemp 
1269*6fee86a4SJeremy Kemp template<typename T> struct ReferenceHandler;
1270*6fee86a4SJeremy Kemp 
1271*6fee86a4SJeremy Kemp /* Specialization for reference-counted types. This depends on the
1272*6fee86a4SJeremy Kemp  * existence of Wrapper<T>::cl_type, and none of the other types having the
1273*6fee86a4SJeremy Kemp  * cl_type member. Note that simplify specifying the parameter as Wrapper<T>
1274*6fee86a4SJeremy Kemp  * does not work, because when using a derived type (e.g. Context) the generic
1275*6fee86a4SJeremy Kemp  * template will provide a better match.
1276*6fee86a4SJeremy Kemp  */
1277*6fee86a4SJeremy Kemp template<typename Func, typename T>
getInfoHelper(Func f,cl_uint name,T * param,int,typename T::cl_type=0)1278*6fee86a4SJeremy Kemp inline cl_int getInfoHelper(Func f, cl_uint name, T* param, int, typename T::cl_type = 0)
1279*6fee86a4SJeremy Kemp {
1280*6fee86a4SJeremy Kemp     typename T::cl_type value;
1281*6fee86a4SJeremy Kemp     cl_int err = f(name, sizeof(value), &value, nullptr);
1282*6fee86a4SJeremy Kemp     if (err != CL_SUCCESS) {
1283*6fee86a4SJeremy Kemp         return err;
1284*6fee86a4SJeremy Kemp     }
1285*6fee86a4SJeremy Kemp     *param = value;
1286*6fee86a4SJeremy Kemp     if (value != nullptr)
1287*6fee86a4SJeremy Kemp     {
1288*6fee86a4SJeremy Kemp         err = param->retain();
1289*6fee86a4SJeremy Kemp         if (err != CL_SUCCESS) {
1290*6fee86a4SJeremy Kemp             return err;
1291*6fee86a4SJeremy Kemp         }
1292*6fee86a4SJeremy Kemp     }
1293*6fee86a4SJeremy Kemp     return CL_SUCCESS;
1294*6fee86a4SJeremy Kemp }
1295*6fee86a4SJeremy Kemp 
1296*6fee86a4SJeremy Kemp #define CL_HPP_PARAM_NAME_INFO_1_0_(F) \
1297*6fee86a4SJeremy Kemp     F(cl_platform_info, CL_PLATFORM_PROFILE, string) \
1298*6fee86a4SJeremy Kemp     F(cl_platform_info, CL_PLATFORM_VERSION, string) \
1299*6fee86a4SJeremy Kemp     F(cl_platform_info, CL_PLATFORM_NAME, string) \
1300*6fee86a4SJeremy Kemp     F(cl_platform_info, CL_PLATFORM_VENDOR, string) \
1301*6fee86a4SJeremy Kemp     F(cl_platform_info, CL_PLATFORM_EXTENSIONS, string) \
1302*6fee86a4SJeremy Kemp     \
1303*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_TYPE, cl_device_type) \
1304*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_VENDOR_ID, cl_uint) \
1305*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_MAX_COMPUTE_UNITS, cl_uint) \
1306*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS, cl_uint) \
1307*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_MAX_WORK_GROUP_SIZE, size_type) \
1308*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_MAX_WORK_ITEM_SIZES, cl::vector<size_type>) \
1309*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR, cl_uint) \
1310*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT, cl_uint) \
1311*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT, cl_uint) \
1312*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG, cl_uint) \
1313*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT, cl_uint) \
1314*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE, cl_uint) \
1315*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_MAX_CLOCK_FREQUENCY, cl_uint) \
1316*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_ADDRESS_BITS, cl_uint) \
1317*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_MAX_READ_IMAGE_ARGS, cl_uint) \
1318*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_MAX_WRITE_IMAGE_ARGS, cl_uint) \
1319*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_MAX_MEM_ALLOC_SIZE, cl_ulong) \
1320*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_IMAGE2D_MAX_WIDTH, size_type) \
1321*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_IMAGE2D_MAX_HEIGHT, size_type) \
1322*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_IMAGE3D_MAX_WIDTH, size_type) \
1323*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_IMAGE3D_MAX_HEIGHT, size_type) \
1324*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_IMAGE3D_MAX_DEPTH, size_type) \
1325*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_IMAGE_SUPPORT, cl_bool) \
1326*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_MAX_PARAMETER_SIZE, size_type) \
1327*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_MAX_SAMPLERS, cl_uint) \
1328*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_MEM_BASE_ADDR_ALIGN, cl_uint) \
1329*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_MIN_DATA_TYPE_ALIGN_SIZE, cl_uint) \
1330*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_SINGLE_FP_CONFIG, cl_device_fp_config) \
1331*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_DOUBLE_FP_CONFIG, cl_device_fp_config) \
1332*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_HALF_FP_CONFIG, cl_device_fp_config) \
1333*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_GLOBAL_MEM_CACHE_TYPE, cl_device_mem_cache_type) \
1334*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE, cl_uint)\
1335*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_GLOBAL_MEM_CACHE_SIZE, cl_ulong) \
1336*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_GLOBAL_MEM_SIZE, cl_ulong) \
1337*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE, cl_ulong) \
1338*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_MAX_CONSTANT_ARGS, cl_uint) \
1339*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_LOCAL_MEM_TYPE, cl_device_local_mem_type) \
1340*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_LOCAL_MEM_SIZE, cl_ulong) \
1341*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_ERROR_CORRECTION_SUPPORT, cl_bool) \
1342*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_PROFILING_TIMER_RESOLUTION, size_type) \
1343*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_ENDIAN_LITTLE, cl_bool) \
1344*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_AVAILABLE, cl_bool) \
1345*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_COMPILER_AVAILABLE, cl_bool) \
1346*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_EXECUTION_CAPABILITIES, cl_device_exec_capabilities) \
1347*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_PLATFORM, cl::Platform) \
1348*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_NAME, string) \
1349*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_VENDOR, string) \
1350*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DRIVER_VERSION, string) \
1351*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_PROFILE, string) \
1352*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_VERSION, string) \
1353*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_EXTENSIONS, string) \
1354*6fee86a4SJeremy Kemp     \
1355*6fee86a4SJeremy Kemp     F(cl_context_info, CL_CONTEXT_REFERENCE_COUNT, cl_uint) \
1356*6fee86a4SJeremy Kemp     F(cl_context_info, CL_CONTEXT_DEVICES, cl::vector<Device>) \
1357*6fee86a4SJeremy Kemp     F(cl_context_info, CL_CONTEXT_PROPERTIES, cl::vector<cl_context_properties>) \
1358*6fee86a4SJeremy Kemp     \
1359*6fee86a4SJeremy Kemp     F(cl_event_info, CL_EVENT_COMMAND_QUEUE, cl::CommandQueue) \
1360*6fee86a4SJeremy Kemp     F(cl_event_info, CL_EVENT_COMMAND_TYPE, cl_command_type) \
1361*6fee86a4SJeremy Kemp     F(cl_event_info, CL_EVENT_REFERENCE_COUNT, cl_uint) \
1362*6fee86a4SJeremy Kemp     F(cl_event_info, CL_EVENT_COMMAND_EXECUTION_STATUS, cl_int) \
1363*6fee86a4SJeremy Kemp     \
1364*6fee86a4SJeremy Kemp     F(cl_profiling_info, CL_PROFILING_COMMAND_QUEUED, cl_ulong) \
1365*6fee86a4SJeremy Kemp     F(cl_profiling_info, CL_PROFILING_COMMAND_SUBMIT, cl_ulong) \
1366*6fee86a4SJeremy Kemp     F(cl_profiling_info, CL_PROFILING_COMMAND_START, cl_ulong) \
1367*6fee86a4SJeremy Kemp     F(cl_profiling_info, CL_PROFILING_COMMAND_END, cl_ulong) \
1368*6fee86a4SJeremy Kemp     \
1369*6fee86a4SJeremy Kemp     F(cl_mem_info, CL_MEM_TYPE, cl_mem_object_type) \
1370*6fee86a4SJeremy Kemp     F(cl_mem_info, CL_MEM_FLAGS, cl_mem_flags) \
1371*6fee86a4SJeremy Kemp     F(cl_mem_info, CL_MEM_SIZE, size_type) \
1372*6fee86a4SJeremy Kemp     F(cl_mem_info, CL_MEM_HOST_PTR, void*) \
1373*6fee86a4SJeremy Kemp     F(cl_mem_info, CL_MEM_MAP_COUNT, cl_uint) \
1374*6fee86a4SJeremy Kemp     F(cl_mem_info, CL_MEM_REFERENCE_COUNT, cl_uint) \
1375*6fee86a4SJeremy Kemp     F(cl_mem_info, CL_MEM_CONTEXT, cl::Context) \
1376*6fee86a4SJeremy Kemp     \
1377*6fee86a4SJeremy Kemp     F(cl_image_info, CL_IMAGE_FORMAT, cl_image_format) \
1378*6fee86a4SJeremy Kemp     F(cl_image_info, CL_IMAGE_ELEMENT_SIZE, size_type) \
1379*6fee86a4SJeremy Kemp     F(cl_image_info, CL_IMAGE_ROW_PITCH, size_type) \
1380*6fee86a4SJeremy Kemp     F(cl_image_info, CL_IMAGE_SLICE_PITCH, size_type) \
1381*6fee86a4SJeremy Kemp     F(cl_image_info, CL_IMAGE_WIDTH, size_type) \
1382*6fee86a4SJeremy Kemp     F(cl_image_info, CL_IMAGE_HEIGHT, size_type) \
1383*6fee86a4SJeremy Kemp     F(cl_image_info, CL_IMAGE_DEPTH, size_type) \
1384*6fee86a4SJeremy Kemp     \
1385*6fee86a4SJeremy Kemp     F(cl_sampler_info, CL_SAMPLER_REFERENCE_COUNT, cl_uint) \
1386*6fee86a4SJeremy Kemp     F(cl_sampler_info, CL_SAMPLER_CONTEXT, cl::Context) \
1387*6fee86a4SJeremy Kemp     F(cl_sampler_info, CL_SAMPLER_NORMALIZED_COORDS, cl_bool) \
1388*6fee86a4SJeremy Kemp     F(cl_sampler_info, CL_SAMPLER_ADDRESSING_MODE, cl_addressing_mode) \
1389*6fee86a4SJeremy Kemp     F(cl_sampler_info, CL_SAMPLER_FILTER_MODE, cl_filter_mode) \
1390*6fee86a4SJeremy Kemp     \
1391*6fee86a4SJeremy Kemp     F(cl_program_info, CL_PROGRAM_REFERENCE_COUNT, cl_uint) \
1392*6fee86a4SJeremy Kemp     F(cl_program_info, CL_PROGRAM_CONTEXT, cl::Context) \
1393*6fee86a4SJeremy Kemp     F(cl_program_info, CL_PROGRAM_NUM_DEVICES, cl_uint) \
1394*6fee86a4SJeremy Kemp     F(cl_program_info, CL_PROGRAM_DEVICES, cl::vector<Device>) \
1395*6fee86a4SJeremy Kemp     F(cl_program_info, CL_PROGRAM_SOURCE, string) \
1396*6fee86a4SJeremy Kemp     F(cl_program_info, CL_PROGRAM_BINARY_SIZES, cl::vector<size_type>) \
1397*6fee86a4SJeremy Kemp     F(cl_program_info, CL_PROGRAM_BINARIES, cl::vector<cl::vector<unsigned char>>) \
1398*6fee86a4SJeremy Kemp     \
1399*6fee86a4SJeremy Kemp     F(cl_program_build_info, CL_PROGRAM_BUILD_STATUS, cl_build_status) \
1400*6fee86a4SJeremy Kemp     F(cl_program_build_info, CL_PROGRAM_BUILD_OPTIONS, string) \
1401*6fee86a4SJeremy Kemp     F(cl_program_build_info, CL_PROGRAM_BUILD_LOG, string) \
1402*6fee86a4SJeremy Kemp     \
1403*6fee86a4SJeremy Kemp     F(cl_kernel_info, CL_KERNEL_FUNCTION_NAME, string) \
1404*6fee86a4SJeremy Kemp     F(cl_kernel_info, CL_KERNEL_NUM_ARGS, cl_uint) \
1405*6fee86a4SJeremy Kemp     F(cl_kernel_info, CL_KERNEL_REFERENCE_COUNT, cl_uint) \
1406*6fee86a4SJeremy Kemp     F(cl_kernel_info, CL_KERNEL_CONTEXT, cl::Context) \
1407*6fee86a4SJeremy Kemp     F(cl_kernel_info, CL_KERNEL_PROGRAM, cl::Program) \
1408*6fee86a4SJeremy Kemp     \
1409*6fee86a4SJeremy Kemp     F(cl_kernel_work_group_info, CL_KERNEL_WORK_GROUP_SIZE, size_type) \
1410*6fee86a4SJeremy Kemp     F(cl_kernel_work_group_info, CL_KERNEL_COMPILE_WORK_GROUP_SIZE, cl::detail::size_t_array) \
1411*6fee86a4SJeremy Kemp     F(cl_kernel_work_group_info, CL_KERNEL_LOCAL_MEM_SIZE, cl_ulong) \
1412*6fee86a4SJeremy Kemp     \
1413*6fee86a4SJeremy Kemp     F(cl_command_queue_info, CL_QUEUE_CONTEXT, cl::Context) \
1414*6fee86a4SJeremy Kemp     F(cl_command_queue_info, CL_QUEUE_DEVICE, cl::Device) \
1415*6fee86a4SJeremy Kemp     F(cl_command_queue_info, CL_QUEUE_REFERENCE_COUNT, cl_uint) \
1416*6fee86a4SJeremy Kemp     F(cl_command_queue_info, CL_QUEUE_PROPERTIES, cl_command_queue_properties)
1417*6fee86a4SJeremy Kemp 
1418*6fee86a4SJeremy Kemp 
1419*6fee86a4SJeremy Kemp #define CL_HPP_PARAM_NAME_INFO_1_1_(F) \
1420*6fee86a4SJeremy Kemp     F(cl_context_info, CL_CONTEXT_NUM_DEVICES, cl_uint)\
1421*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_PREFERRED_VECTOR_WIDTH_HALF, cl_uint) \
1422*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_CHAR, cl_uint) \
1423*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_SHORT, cl_uint) \
1424*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_INT, cl_uint) \
1425*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_LONG, cl_uint) \
1426*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_FLOAT, cl_uint) \
1427*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_DOUBLE, cl_uint) \
1428*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_NATIVE_VECTOR_WIDTH_HALF, cl_uint) \
1429*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_OPENCL_C_VERSION, string) \
1430*6fee86a4SJeremy Kemp     \
1431*6fee86a4SJeremy Kemp     F(cl_mem_info, CL_MEM_ASSOCIATED_MEMOBJECT, cl::Memory) \
1432*6fee86a4SJeremy Kemp     F(cl_mem_info, CL_MEM_OFFSET, size_type) \
1433*6fee86a4SJeremy Kemp     \
1434*6fee86a4SJeremy Kemp     F(cl_kernel_work_group_info, CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE, size_type) \
1435*6fee86a4SJeremy Kemp     F(cl_kernel_work_group_info, CL_KERNEL_PRIVATE_MEM_SIZE, cl_ulong) \
1436*6fee86a4SJeremy Kemp     \
1437*6fee86a4SJeremy Kemp     F(cl_event_info, CL_EVENT_CONTEXT, cl::Context)
1438*6fee86a4SJeremy Kemp 
1439*6fee86a4SJeremy Kemp #define CL_HPP_PARAM_NAME_INFO_1_2_(F) \
1440*6fee86a4SJeremy Kemp     F(cl_program_info, CL_PROGRAM_NUM_KERNELS, size_type) \
1441*6fee86a4SJeremy Kemp     F(cl_program_info, CL_PROGRAM_KERNEL_NAMES, string) \
1442*6fee86a4SJeremy Kemp     \
1443*6fee86a4SJeremy Kemp     F(cl_program_build_info, CL_PROGRAM_BINARY_TYPE, cl_program_binary_type) \
1444*6fee86a4SJeremy Kemp     \
1445*6fee86a4SJeremy Kemp     F(cl_kernel_info, CL_KERNEL_ATTRIBUTES, string) \
1446*6fee86a4SJeremy Kemp     \
1447*6fee86a4SJeremy Kemp     F(cl_kernel_arg_info, CL_KERNEL_ARG_ADDRESS_QUALIFIER, cl_kernel_arg_address_qualifier) \
1448*6fee86a4SJeremy Kemp     F(cl_kernel_arg_info, CL_KERNEL_ARG_ACCESS_QUALIFIER, cl_kernel_arg_access_qualifier) \
1449*6fee86a4SJeremy Kemp     F(cl_kernel_arg_info, CL_KERNEL_ARG_TYPE_NAME, string) \
1450*6fee86a4SJeremy Kemp     F(cl_kernel_arg_info, CL_KERNEL_ARG_NAME, string) \
1451*6fee86a4SJeremy Kemp     F(cl_kernel_arg_info, CL_KERNEL_ARG_TYPE_QUALIFIER, cl_kernel_arg_type_qualifier) \
1452*6fee86a4SJeremy Kemp     \
1453*6fee86a4SJeremy Kemp     F(cl_kernel_work_group_info, CL_KERNEL_GLOBAL_WORK_SIZE, cl::detail::size_t_array) \
1454*6fee86a4SJeremy Kemp     \
1455*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_LINKER_AVAILABLE, cl_bool) \
1456*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_IMAGE_MAX_BUFFER_SIZE, size_type) \
1457*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_IMAGE_MAX_ARRAY_SIZE, size_type) \
1458*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_PARENT_DEVICE, cl::Device) \
1459*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_PARTITION_MAX_SUB_DEVICES, cl_uint) \
1460*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_PARTITION_PROPERTIES, cl::vector<cl_device_partition_property>) \
1461*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_PARTITION_TYPE, cl::vector<cl_device_partition_property>)  \
1462*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_REFERENCE_COUNT, cl_uint) \
1463*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_PREFERRED_INTEROP_USER_SYNC, cl_bool) \
1464*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_PARTITION_AFFINITY_DOMAIN, cl_device_affinity_domain) \
1465*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_BUILT_IN_KERNELS, string) \
1466*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_PRINTF_BUFFER_SIZE, size_type) \
1467*6fee86a4SJeremy Kemp     \
1468*6fee86a4SJeremy Kemp     F(cl_image_info, CL_IMAGE_ARRAY_SIZE, size_type) \
1469*6fee86a4SJeremy Kemp     F(cl_image_info, CL_IMAGE_NUM_MIP_LEVELS, cl_uint) \
1470*6fee86a4SJeremy Kemp     F(cl_image_info, CL_IMAGE_NUM_SAMPLES, cl_uint)
1471*6fee86a4SJeremy Kemp 
1472*6fee86a4SJeremy Kemp #define CL_HPP_PARAM_NAME_INFO_2_0_(F) \
1473*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_QUEUE_ON_HOST_PROPERTIES, cl_command_queue_properties) \
1474*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_QUEUE_ON_DEVICE_PROPERTIES, cl_command_queue_properties) \
1475*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_QUEUE_ON_DEVICE_PREFERRED_SIZE, cl_uint) \
1476*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_QUEUE_ON_DEVICE_MAX_SIZE, cl_uint) \
1477*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_MAX_ON_DEVICE_QUEUES, cl_uint) \
1478*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_MAX_ON_DEVICE_EVENTS, cl_uint) \
1479*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_MAX_PIPE_ARGS, cl_uint) \
1480*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_PIPE_MAX_ACTIVE_RESERVATIONS, cl_uint) \
1481*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_PIPE_MAX_PACKET_SIZE, cl_uint) \
1482*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_SVM_CAPABILITIES, cl_device_svm_capabilities) \
1483*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_PREFERRED_PLATFORM_ATOMIC_ALIGNMENT, cl_uint) \
1484*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_PREFERRED_GLOBAL_ATOMIC_ALIGNMENT, cl_uint) \
1485*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_PREFERRED_LOCAL_ATOMIC_ALIGNMENT, cl_uint) \
1486*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_IMAGE_PITCH_ALIGNMENT, cl_uint) \
1487*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_IMAGE_BASE_ADDRESS_ALIGNMENT, cl_uint) \
1488*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_MAX_READ_WRITE_IMAGE_ARGS, cl_uint ) \
1489*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_MAX_GLOBAL_VARIABLE_SIZE, size_type ) \
1490*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_GLOBAL_VARIABLE_PREFERRED_TOTAL_SIZE, size_type ) \
1491*6fee86a4SJeremy Kemp     F(cl_profiling_info, CL_PROFILING_COMMAND_COMPLETE, cl_ulong) \
1492*6fee86a4SJeremy Kemp     F(cl_kernel_exec_info, CL_KERNEL_EXEC_INFO_SVM_FINE_GRAIN_SYSTEM, cl_bool) \
1493*6fee86a4SJeremy Kemp     F(cl_kernel_exec_info, CL_KERNEL_EXEC_INFO_SVM_PTRS, void**) \
1494*6fee86a4SJeremy Kemp     F(cl_command_queue_info, CL_QUEUE_SIZE, cl_uint) \
1495*6fee86a4SJeremy Kemp     F(cl_mem_info, CL_MEM_USES_SVM_POINTER, cl_bool) \
1496*6fee86a4SJeremy Kemp     F(cl_program_build_info, CL_PROGRAM_BUILD_GLOBAL_VARIABLE_TOTAL_SIZE, size_type) \
1497*6fee86a4SJeremy Kemp     F(cl_pipe_info, CL_PIPE_PACKET_SIZE, cl_uint) \
1498*6fee86a4SJeremy Kemp     F(cl_pipe_info, CL_PIPE_MAX_PACKETS, cl_uint)
1499*6fee86a4SJeremy Kemp 
1500*6fee86a4SJeremy Kemp #define CL_HPP_PARAM_NAME_INFO_SUBGROUP_KHR_(F) \
1501*6fee86a4SJeremy Kemp     F(cl_kernel_sub_group_info, CL_KERNEL_MAX_SUB_GROUP_SIZE_FOR_NDRANGE_KHR, size_type) \
1502*6fee86a4SJeremy Kemp     F(cl_kernel_sub_group_info, CL_KERNEL_SUB_GROUP_COUNT_FOR_NDRANGE_KHR, size_type)
1503*6fee86a4SJeremy Kemp 
1504*6fee86a4SJeremy Kemp #define CL_HPP_PARAM_NAME_INFO_IL_KHR_(F) \
1505*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_IL_VERSION_KHR, string) \
1506*6fee86a4SJeremy Kemp     F(cl_program_info, CL_PROGRAM_IL_KHR, cl::vector<unsigned char>)
1507*6fee86a4SJeremy Kemp 
1508*6fee86a4SJeremy Kemp #define CL_HPP_PARAM_NAME_INFO_2_1_(F) \
1509*6fee86a4SJeremy Kemp     F(cl_platform_info, CL_PLATFORM_HOST_TIMER_RESOLUTION, cl_ulong) \
1510*6fee86a4SJeremy Kemp     F(cl_program_info, CL_PROGRAM_IL, cl::vector<unsigned char>) \
1511*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_MAX_NUM_SUB_GROUPS, cl_uint) \
1512*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_IL_VERSION, string) \
1513*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_SUB_GROUP_INDEPENDENT_FORWARD_PROGRESS, cl_bool) \
1514*6fee86a4SJeremy Kemp     F(cl_command_queue_info, CL_QUEUE_DEVICE_DEFAULT, cl::DeviceCommandQueue) \
1515*6fee86a4SJeremy Kemp     F(cl_kernel_sub_group_info, CL_KERNEL_MAX_SUB_GROUP_SIZE_FOR_NDRANGE, size_type) \
1516*6fee86a4SJeremy Kemp     F(cl_kernel_sub_group_info, CL_KERNEL_SUB_GROUP_COUNT_FOR_NDRANGE, size_type) \
1517*6fee86a4SJeremy Kemp     F(cl_kernel_sub_group_info, CL_KERNEL_LOCAL_SIZE_FOR_SUB_GROUP_COUNT, cl::detail::size_t_array) \
1518*6fee86a4SJeremy Kemp     F(cl_kernel_sub_group_info, CL_KERNEL_MAX_NUM_SUB_GROUPS, size_type) \
1519*6fee86a4SJeremy Kemp     F(cl_kernel_sub_group_info, CL_KERNEL_COMPILE_NUM_SUB_GROUPS, size_type)
1520*6fee86a4SJeremy Kemp 
1521*6fee86a4SJeremy Kemp #define CL_HPP_PARAM_NAME_INFO_2_2_(F) \
1522*6fee86a4SJeremy Kemp     F(cl_program_info, CL_PROGRAM_SCOPE_GLOBAL_CTORS_PRESENT, cl_bool) \
1523*6fee86a4SJeremy Kemp     F(cl_program_info, CL_PROGRAM_SCOPE_GLOBAL_DTORS_PRESENT, cl_bool)
1524*6fee86a4SJeremy Kemp 
1525*6fee86a4SJeremy Kemp #define CL_HPP_PARAM_NAME_DEVICE_FISSION_EXT_(F) \
1526*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_PARENT_DEVICE_EXT, cl::Device) \
1527*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_PARTITION_TYPES_EXT, cl::vector<cl_device_partition_property_ext>) \
1528*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_AFFINITY_DOMAINS_EXT, cl::vector<cl_device_partition_property_ext>) \
1529*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_REFERENCE_COUNT_EXT , cl_uint) \
1530*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_PARTITION_STYLE_EXT, cl::vector<cl_device_partition_property_ext>)
1531*6fee86a4SJeremy Kemp 
1532*6fee86a4SJeremy Kemp #define CL_HPP_PARAM_NAME_CL_KHR_EXTENDED_VERSIONING_CL3_SHARED_(F) \
1533*6fee86a4SJeremy Kemp     F(cl_platform_info, CL_PLATFORM_NUMERIC_VERSION_KHR, cl_version_khr) \
1534*6fee86a4SJeremy Kemp     F(cl_platform_info, CL_PLATFORM_EXTENSIONS_WITH_VERSION_KHR, cl::vector<cl_name_version_khr>) \
1535*6fee86a4SJeremy Kemp     \
1536*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_NUMERIC_VERSION_KHR, cl_version_khr) \
1537*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_EXTENSIONS_WITH_VERSION_KHR, cl::vector<cl_name_version_khr>) \
1538*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_ILS_WITH_VERSION_KHR, cl::vector<cl_name_version_khr>) \
1539*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_BUILT_IN_KERNELS_WITH_VERSION_KHR, cl::vector<cl_name_version_khr>)
1540*6fee86a4SJeremy Kemp 
1541*6fee86a4SJeremy Kemp #define CL_HPP_PARAM_NAME_CL_KHR_EXTENDED_VERSIONING_KHRONLY_(F) \
1542*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_OPENCL_C_NUMERIC_VERSION_KHR, cl_version_khr)
1543*6fee86a4SJeremy Kemp 
1544*6fee86a4SJeremy Kemp // Note: the query for CL_SEMAPHORE_DEVICE_HANDLE_LIST_KHR is handled specially!
1545*6fee86a4SJeremy Kemp #define CL_HPP_PARAM_NAME_CL_KHR_SEMAPHORE_(F) \
1546*6fee86a4SJeremy Kemp     F(cl_semaphore_info_khr, CL_SEMAPHORE_CONTEXT_KHR, cl::Context) \
1547*6fee86a4SJeremy Kemp     F(cl_semaphore_info_khr, CL_SEMAPHORE_REFERENCE_COUNT_KHR, cl_uint) \
1548*6fee86a4SJeremy Kemp     F(cl_semaphore_info_khr, CL_SEMAPHORE_PROPERTIES_KHR, cl::vector<cl_semaphore_properties_khr>) \
1549*6fee86a4SJeremy Kemp     F(cl_semaphore_info_khr, CL_SEMAPHORE_TYPE_KHR, cl_semaphore_type_khr) \
1550*6fee86a4SJeremy Kemp     F(cl_semaphore_info_khr, CL_SEMAPHORE_PAYLOAD_KHR, cl_semaphore_payload_khr) \
1551*6fee86a4SJeremy Kemp     F(cl_platform_info, CL_PLATFORM_SEMAPHORE_TYPES_KHR,  cl::vector<cl_semaphore_type_khr>) \
1552*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_SEMAPHORE_TYPES_KHR,      cl::vector<cl_semaphore_type_khr>) \
1553*6fee86a4SJeremy Kemp 
1554*6fee86a4SJeremy Kemp #define CL_HPP_PARAM_NAME_CL_KHR_EXTERNAL_MEMORY_(F) \
1555*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_EXTERNAL_MEMORY_IMPORT_HANDLE_TYPES_KHR, cl::vector<cl::ExternalMemoryType>) \
1556*6fee86a4SJeremy Kemp     F(cl_platform_info, CL_PLATFORM_EXTERNAL_MEMORY_IMPORT_HANDLE_TYPES_KHR, cl::vector<cl::ExternalMemoryType>)
1557*6fee86a4SJeremy Kemp 
1558*6fee86a4SJeremy Kemp #define CL_HPP_PARAM_NAME_CL_KHR_EXTERNAL_SEMAPHORE_(F) \
1559*6fee86a4SJeremy Kemp     F(cl_platform_info, CL_PLATFORM_SEMAPHORE_IMPORT_HANDLE_TYPES_KHR,  cl::vector<cl_external_semaphore_handle_type_khr>) \
1560*6fee86a4SJeremy Kemp     F(cl_platform_info, CL_PLATFORM_SEMAPHORE_EXPORT_HANDLE_TYPES_KHR,  cl::vector<cl_external_semaphore_handle_type_khr>) \
1561*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_SEMAPHORE_IMPORT_HANDLE_TYPES_KHR,      cl::vector<cl_external_semaphore_handle_type_khr>) \
1562*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_SEMAPHORE_EXPORT_HANDLE_TYPES_KHR,      cl::vector<cl_external_semaphore_handle_type_khr>) \
1563*6fee86a4SJeremy Kemp     F(cl_semaphore_info_khr, CL_SEMAPHORE_EXPORT_HANDLE_TYPES_KHR,      cl::vector<cl_external_semaphore_handle_type_khr>) \
1564*6fee86a4SJeremy Kemp 
1565*6fee86a4SJeremy Kemp #define CL_HPP_PARAM_NAME_CL_KHR_EXTERNAL_SEMAPHORE_DX_FENCE_EXT(F) \
1566*6fee86a4SJeremy Kemp     F(cl_external_semaphore_handle_type_khr, CL_SEMAPHORE_HANDLE_D3D12_FENCE_KHR, void*) \
1567*6fee86a4SJeremy Kemp 
1568*6fee86a4SJeremy Kemp #define CL_HPP_PARAM_NAME_CL_KHR_EXTERNAL_SEMAPHORE_OPAQUE_FD_EXT(F) \
1569*6fee86a4SJeremy Kemp     F(cl_external_semaphore_handle_type_khr, CL_SEMAPHORE_HANDLE_OPAQUE_FD_KHR, int) \
1570*6fee86a4SJeremy Kemp 
1571*6fee86a4SJeremy Kemp #define CL_HPP_PARAM_NAME_CL_KHR_EXTERNAL_SEMAPHORE_SYNC_FD_EXT(F) \
1572*6fee86a4SJeremy Kemp     F(cl_external_semaphore_handle_type_khr, CL_SEMAPHORE_HANDLE_SYNC_FD_KHR, int) \
1573*6fee86a4SJeremy Kemp 
1574*6fee86a4SJeremy Kemp #define CL_HPP_PARAM_NAME_CL_KHR_EXTERNAL_SEMAPHORE_WIN32_EXT(F) \
1575*6fee86a4SJeremy Kemp     F(cl_external_semaphore_handle_type_khr, CL_SEMAPHORE_HANDLE_OPAQUE_WIN32_KHR, void*) \
1576*6fee86a4SJeremy Kemp     F(cl_external_semaphore_handle_type_khr, CL_SEMAPHORE_HANDLE_OPAQUE_WIN32_KMT_KHR, void*) \
1577*6fee86a4SJeremy Kemp 
1578*6fee86a4SJeremy Kemp #define CL_HPP_PARAM_NAME_INFO_3_0_(F) \
1579*6fee86a4SJeremy Kemp     F(cl_platform_info, CL_PLATFORM_NUMERIC_VERSION, cl_version) \
1580*6fee86a4SJeremy Kemp     F(cl_platform_info, CL_PLATFORM_EXTENSIONS_WITH_VERSION, cl::vector<cl_name_version>) \
1581*6fee86a4SJeremy Kemp     \
1582*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_NUMERIC_VERSION, cl_version) \
1583*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_EXTENSIONS_WITH_VERSION, cl::vector<cl_name_version>) \
1584*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_ILS_WITH_VERSION, cl::vector<cl_name_version>) \
1585*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_BUILT_IN_KERNELS_WITH_VERSION, cl::vector<cl_name_version>) \
1586*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_ATOMIC_MEMORY_CAPABILITIES, cl_device_atomic_capabilities) \
1587*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_ATOMIC_FENCE_CAPABILITIES, cl_device_atomic_capabilities) \
1588*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_NON_UNIFORM_WORK_GROUP_SUPPORT, cl_bool) \
1589*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_OPENCL_C_ALL_VERSIONS, cl::vector<cl_name_version>) \
1590*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_PREFERRED_WORK_GROUP_SIZE_MULTIPLE, size_type) \
1591*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_WORK_GROUP_COLLECTIVE_FUNCTIONS_SUPPORT, cl_bool) \
1592*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_GENERIC_ADDRESS_SPACE_SUPPORT, cl_bool) \
1593*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_OPENCL_C_FEATURES, cl::vector<cl_name_version>) \
1594*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_DEVICE_ENQUEUE_CAPABILITIES, cl_device_device_enqueue_capabilities) \
1595*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_PIPE_SUPPORT, cl_bool) \
1596*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_LATEST_CONFORMANCE_VERSION_PASSED, string) \
1597*6fee86a4SJeremy Kemp     \
1598*6fee86a4SJeremy Kemp     F(cl_command_queue_info, CL_QUEUE_PROPERTIES_ARRAY, cl::vector<cl_queue_properties>) \
1599*6fee86a4SJeremy Kemp     F(cl_mem_info, CL_MEM_PROPERTIES, cl::vector<cl_mem_properties>) \
1600*6fee86a4SJeremy Kemp     F(cl_pipe_info, CL_PIPE_PROPERTIES, cl::vector<cl_pipe_properties>) \
1601*6fee86a4SJeremy Kemp     F(cl_sampler_info, CL_SAMPLER_PROPERTIES, cl::vector<cl_sampler_properties>) \
1602*6fee86a4SJeremy Kemp 
1603*6fee86a4SJeremy Kemp #define CL_HPP_PARAM_NAME_CL_IMAGE_REQUIREMENTS_EXT(F) \
1604*6fee86a4SJeremy Kemp     F(cl_image_requirements_info_ext, CL_IMAGE_REQUIREMENTS_ROW_PITCH_ALIGNMENT_EXT, size_type) \
1605*6fee86a4SJeremy Kemp     F(cl_image_requirements_info_ext, CL_IMAGE_REQUIREMENTS_BASE_ADDRESS_ALIGNMENT_EXT, size_type) \
1606*6fee86a4SJeremy Kemp     F(cl_image_requirements_info_ext, CL_IMAGE_REQUIREMENTS_SIZE_EXT, size_type) \
1607*6fee86a4SJeremy Kemp     F(cl_image_requirements_info_ext, CL_IMAGE_REQUIREMENTS_MAX_WIDTH_EXT, cl_uint) \
1608*6fee86a4SJeremy Kemp     F(cl_image_requirements_info_ext, CL_IMAGE_REQUIREMENTS_MAX_HEIGHT_EXT, cl_uint) \
1609*6fee86a4SJeremy Kemp     F(cl_image_requirements_info_ext, CL_IMAGE_REQUIREMENTS_MAX_DEPTH_EXT, cl_uint) \
1610*6fee86a4SJeremy Kemp     F(cl_image_requirements_info_ext, CL_IMAGE_REQUIREMENTS_MAX_ARRAY_SIZE_EXT, cl_uint) \
1611*6fee86a4SJeremy Kemp 
1612*6fee86a4SJeremy Kemp #define CL_HPP_PARAM_NAME_CL_IMAGE_REQUIREMENTS_SLICE_PITCH_ALIGNMENT_EXT(F) \
1613*6fee86a4SJeremy Kemp     F(cl_image_requirements_info_ext, CL_IMAGE_REQUIREMENTS_SLICE_PITCH_ALIGNMENT_EXT, size_type) \
1614*6fee86a4SJeremy Kemp 
1615*6fee86a4SJeremy Kemp template <typename enum_type, cl_int Name>
1616*6fee86a4SJeremy Kemp struct param_traits {};
1617*6fee86a4SJeremy Kemp 
1618*6fee86a4SJeremy Kemp #define CL_HPP_DECLARE_PARAM_TRAITS_(token, param_name, T) \
1619*6fee86a4SJeremy Kemp struct token;                                        \
1620*6fee86a4SJeremy Kemp template<>                                           \
1621*6fee86a4SJeremy Kemp struct param_traits<detail:: token,param_name>       \
1622*6fee86a4SJeremy Kemp {                                                    \
1623*6fee86a4SJeremy Kemp     enum { value = param_name };                     \
1624*6fee86a4SJeremy Kemp     typedef T param_type;                            \
1625*6fee86a4SJeremy Kemp };
1626*6fee86a4SJeremy Kemp 
1627*6fee86a4SJeremy Kemp CL_HPP_PARAM_NAME_INFO_1_0_(CL_HPP_DECLARE_PARAM_TRAITS_)
1628*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 110
1629*6fee86a4SJeremy Kemp CL_HPP_PARAM_NAME_INFO_1_1_(CL_HPP_DECLARE_PARAM_TRAITS_)
1630*6fee86a4SJeremy Kemp #endif // CL_HPP_TARGET_OPENCL_VERSION >= 110
1631*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 120
1632*6fee86a4SJeremy Kemp CL_HPP_PARAM_NAME_INFO_1_2_(CL_HPP_DECLARE_PARAM_TRAITS_)
1633*6fee86a4SJeremy Kemp #endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
1634*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 200
1635*6fee86a4SJeremy Kemp CL_HPP_PARAM_NAME_INFO_2_0_(CL_HPP_DECLARE_PARAM_TRAITS_)
1636*6fee86a4SJeremy Kemp #endif // CL_HPP_TARGET_OPENCL_VERSION >= 200
1637*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 210
1638*6fee86a4SJeremy Kemp CL_HPP_PARAM_NAME_INFO_2_1_(CL_HPP_DECLARE_PARAM_TRAITS_)
1639*6fee86a4SJeremy Kemp #endif // CL_HPP_TARGET_OPENCL_VERSION >= 210
1640*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 220
1641*6fee86a4SJeremy Kemp CL_HPP_PARAM_NAME_INFO_2_2_(CL_HPP_DECLARE_PARAM_TRAITS_)
1642*6fee86a4SJeremy Kemp #endif // CL_HPP_TARGET_OPENCL_VERSION >= 220
1643*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 300
1644*6fee86a4SJeremy Kemp CL_HPP_PARAM_NAME_INFO_3_0_(CL_HPP_DECLARE_PARAM_TRAITS_)
1645*6fee86a4SJeremy Kemp #endif // CL_HPP_TARGET_OPENCL_VERSION >= 300
1646*6fee86a4SJeremy Kemp 
1647*6fee86a4SJeremy Kemp #if defined(cl_khr_subgroups) && CL_HPP_TARGET_OPENCL_VERSION < 210
1648*6fee86a4SJeremy Kemp CL_HPP_PARAM_NAME_INFO_SUBGROUP_KHR_(CL_HPP_DECLARE_PARAM_TRAITS_)
1649*6fee86a4SJeremy Kemp #endif // #if defined(cl_khr_subgroups) && CL_HPP_TARGET_OPENCL_VERSION < 210
1650*6fee86a4SJeremy Kemp 
1651*6fee86a4SJeremy Kemp #if defined(cl_khr_il_program) && CL_HPP_TARGET_OPENCL_VERSION < 210
1652*6fee86a4SJeremy Kemp CL_HPP_PARAM_NAME_INFO_IL_KHR_(CL_HPP_DECLARE_PARAM_TRAITS_)
1653*6fee86a4SJeremy Kemp #endif // #if defined(cl_khr_il_program) && CL_HPP_TARGET_OPENCL_VERSION < 210
1654*6fee86a4SJeremy Kemp 
1655*6fee86a4SJeremy Kemp 
1656*6fee86a4SJeremy Kemp // Flags deprecated in OpenCL 2.0
1657*6fee86a4SJeremy Kemp #define CL_HPP_PARAM_NAME_INFO_1_0_DEPRECATED_IN_2_0_(F) \
1658*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_QUEUE_PROPERTIES, cl_command_queue_properties)
1659*6fee86a4SJeremy Kemp 
1660*6fee86a4SJeremy Kemp #define CL_HPP_PARAM_NAME_INFO_1_1_DEPRECATED_IN_2_0_(F) \
1661*6fee86a4SJeremy Kemp     F(cl_device_info, CL_DEVICE_HOST_UNIFIED_MEMORY, cl_bool)
1662*6fee86a4SJeremy Kemp 
1663*6fee86a4SJeremy Kemp #define CL_HPP_PARAM_NAME_INFO_1_2_DEPRECATED_IN_2_0_(F) \
1664*6fee86a4SJeremy Kemp     F(cl_image_info, CL_IMAGE_BUFFER, cl::Buffer)
1665*6fee86a4SJeremy Kemp 
1666*6fee86a4SJeremy Kemp // Include deprecated query flags based on versions
1667*6fee86a4SJeremy Kemp // Only include deprecated 1.0 flags if 2.0 not active as there is an enum clash
1668*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION > 100 && CL_HPP_MINIMUM_OPENCL_VERSION < 200 && CL_HPP_TARGET_OPENCL_VERSION < 200
1669*6fee86a4SJeremy Kemp CL_HPP_PARAM_NAME_INFO_1_0_DEPRECATED_IN_2_0_(CL_HPP_DECLARE_PARAM_TRAITS_)
1670*6fee86a4SJeremy Kemp #endif // CL_HPP_MINIMUM_OPENCL_VERSION < 110
1671*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION > 110 && CL_HPP_MINIMUM_OPENCL_VERSION < 200
1672*6fee86a4SJeremy Kemp CL_HPP_PARAM_NAME_INFO_1_1_DEPRECATED_IN_2_0_(CL_HPP_DECLARE_PARAM_TRAITS_)
1673*6fee86a4SJeremy Kemp #endif // CL_HPP_MINIMUM_OPENCL_VERSION < 120
1674*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION > 120 && CL_HPP_MINIMUM_OPENCL_VERSION < 200
1675*6fee86a4SJeremy Kemp CL_HPP_PARAM_NAME_INFO_1_2_DEPRECATED_IN_2_0_(CL_HPP_DECLARE_PARAM_TRAITS_)
1676*6fee86a4SJeremy Kemp #endif // CL_HPP_MINIMUM_OPENCL_VERSION < 200
1677*6fee86a4SJeremy Kemp 
1678*6fee86a4SJeremy Kemp #if defined(cl_ext_device_fission)
1679*6fee86a4SJeremy Kemp CL_HPP_PARAM_NAME_DEVICE_FISSION_EXT_(CL_HPP_DECLARE_PARAM_TRAITS_)
1680*6fee86a4SJeremy Kemp #endif // cl_ext_device_fission
1681*6fee86a4SJeremy Kemp 
1682*6fee86a4SJeremy Kemp #if defined(cl_khr_extended_versioning)
1683*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION < 300
1684*6fee86a4SJeremy Kemp CL_HPP_PARAM_NAME_CL_KHR_EXTENDED_VERSIONING_CL3_SHARED_(CL_HPP_DECLARE_PARAM_TRAITS_)
1685*6fee86a4SJeremy Kemp #endif // CL_HPP_TARGET_OPENCL_VERSION < 300
1686*6fee86a4SJeremy Kemp CL_HPP_PARAM_NAME_CL_KHR_EXTENDED_VERSIONING_KHRONLY_(CL_HPP_DECLARE_PARAM_TRAITS_)
1687*6fee86a4SJeremy Kemp #endif // cl_khr_extended_versioning
1688*6fee86a4SJeremy Kemp 
1689*6fee86a4SJeremy Kemp #if defined(cl_khr_semaphore)
1690*6fee86a4SJeremy Kemp CL_HPP_PARAM_NAME_CL_KHR_SEMAPHORE_(CL_HPP_DECLARE_PARAM_TRAITS_)
1691*6fee86a4SJeremy Kemp #if defined(CL_SEMAPHORE_DEVICE_HANDLE_LIST_KHR)
1692*6fee86a4SJeremy Kemp CL_HPP_DECLARE_PARAM_TRAITS_(cl_semaphore_info_khr, CL_SEMAPHORE_DEVICE_HANDLE_LIST_KHR, cl::vector<cl::Device>)
1693*6fee86a4SJeremy Kemp #endif // defined(CL_SEMAPHORE_DEVICE_HANDLE_LIST_KHR)
1694*6fee86a4SJeremy Kemp #endif // defined(cl_khr_semaphore)
1695*6fee86a4SJeremy Kemp 
1696*6fee86a4SJeremy Kemp #ifdef cl_khr_external_memory
1697*6fee86a4SJeremy Kemp CL_HPP_PARAM_NAME_CL_KHR_EXTERNAL_MEMORY_(CL_HPP_DECLARE_PARAM_TRAITS_)
1698*6fee86a4SJeremy Kemp #endif // cl_khr_external_memory
1699*6fee86a4SJeremy Kemp 
1700*6fee86a4SJeremy Kemp #if defined(cl_khr_external_semaphore)
1701*6fee86a4SJeremy Kemp CL_HPP_PARAM_NAME_CL_KHR_EXTERNAL_SEMAPHORE_(CL_HPP_DECLARE_PARAM_TRAITS_)
1702*6fee86a4SJeremy Kemp #endif // cl_khr_external_semaphore
1703*6fee86a4SJeremy Kemp 
1704*6fee86a4SJeremy Kemp #if defined(cl_khr_external_semaphore_dx_fence)
1705*6fee86a4SJeremy Kemp CL_HPP_PARAM_NAME_CL_KHR_EXTERNAL_SEMAPHORE_DX_FENCE_EXT(CL_HPP_DECLARE_PARAM_TRAITS_)
1706*6fee86a4SJeremy Kemp #endif // cl_khr_external_semaphore_dx_fence
1707*6fee86a4SJeremy Kemp #if defined(cl_khr_external_semaphore_opaque_fd)
1708*6fee86a4SJeremy Kemp CL_HPP_PARAM_NAME_CL_KHR_EXTERNAL_SEMAPHORE_OPAQUE_FD_EXT(CL_HPP_DECLARE_PARAM_TRAITS_)
1709*6fee86a4SJeremy Kemp #endif // cl_khr_external_semaphore_opaque_fd
1710*6fee86a4SJeremy Kemp #if defined(cl_khr_external_semaphore_sync_fd)
1711*6fee86a4SJeremy Kemp CL_HPP_PARAM_NAME_CL_KHR_EXTERNAL_SEMAPHORE_SYNC_FD_EXT(CL_HPP_DECLARE_PARAM_TRAITS_)
1712*6fee86a4SJeremy Kemp #endif // cl_khr_external_semaphore_sync_fd
1713*6fee86a4SJeremy Kemp #if defined(cl_khr_external_semaphore_win32)
1714*6fee86a4SJeremy Kemp CL_HPP_PARAM_NAME_CL_KHR_EXTERNAL_SEMAPHORE_WIN32_EXT(CL_HPP_DECLARE_PARAM_TRAITS_)
1715*6fee86a4SJeremy Kemp #endif // cl_khr_external_semaphore_win32
1716*6fee86a4SJeremy Kemp 
1717*6fee86a4SJeremy Kemp #if defined(cl_khr_device_uuid)
1718*6fee86a4SJeremy Kemp using uuid_array = array<cl_uchar, CL_UUID_SIZE_KHR>;
1719*6fee86a4SJeremy Kemp using luid_array = array<cl_uchar, CL_LUID_SIZE_KHR>;
CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info,CL_DEVICE_UUID_KHR,uuid_array)1720*6fee86a4SJeremy Kemp CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_UUID_KHR, uuid_array)
1721*6fee86a4SJeremy Kemp CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DRIVER_UUID_KHR, uuid_array)
1722*6fee86a4SJeremy Kemp CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_LUID_VALID_KHR, cl_bool)
1723*6fee86a4SJeremy Kemp CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_LUID_KHR, luid_array)
1724*6fee86a4SJeremy Kemp CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_NODE_MASK_KHR, cl_uint)
1725*6fee86a4SJeremy Kemp #endif
1726*6fee86a4SJeremy Kemp 
1727*6fee86a4SJeremy Kemp #if defined(cl_khr_pci_bus_info)
1728*6fee86a4SJeremy Kemp CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_PCI_BUS_INFO_KHR, cl_device_pci_bus_info_khr)
1729*6fee86a4SJeremy Kemp #endif
1730*6fee86a4SJeremy Kemp 
1731*6fee86a4SJeremy Kemp // Note: some headers do not define cl_khr_image2d_from_buffer
1732*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION < 200
1733*6fee86a4SJeremy Kemp #if defined(CL_DEVICE_IMAGE_PITCH_ALIGNMENT_KHR)
1734*6fee86a4SJeremy Kemp CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_IMAGE_PITCH_ALIGNMENT_KHR, cl_uint)
1735*6fee86a4SJeremy Kemp #endif
1736*6fee86a4SJeremy Kemp #if defined(CL_DEVICE_IMAGE_BASE_ADDRESS_ALIGNMENT_KHR)
1737*6fee86a4SJeremy Kemp CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_IMAGE_BASE_ADDRESS_ALIGNMENT_KHR, cl_uint)
1738*6fee86a4SJeremy Kemp #endif
1739*6fee86a4SJeremy Kemp #endif // CL_HPP_TARGET_OPENCL_VERSION < 200
1740*6fee86a4SJeremy Kemp 
1741*6fee86a4SJeremy Kemp #if defined(cl_khr_integer_dot_product)
1742*6fee86a4SJeremy Kemp CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_INTEGER_DOT_PRODUCT_CAPABILITIES_KHR, cl_device_integer_dot_product_capabilities_khr)
1743*6fee86a4SJeremy Kemp #if defined(CL_DEVICE_INTEGER_DOT_PRODUCT_ACCELERATION_PROPERTIES_8BIT_KHR)
1744*6fee86a4SJeremy Kemp CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_INTEGER_DOT_PRODUCT_ACCELERATION_PROPERTIES_8BIT_KHR, cl_device_integer_dot_product_acceleration_properties_khr)
1745*6fee86a4SJeremy Kemp CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_INTEGER_DOT_PRODUCT_ACCELERATION_PROPERTIES_4x8BIT_PACKED_KHR, cl_device_integer_dot_product_acceleration_properties_khr)
1746*6fee86a4SJeremy Kemp #endif // defined(CL_DEVICE_INTEGER_DOT_PRODUCT_ACCELERATION_PROPERTIES_8BIT_KHR)
1747*6fee86a4SJeremy Kemp #endif // defined(cl_khr_integer_dot_product)
1748*6fee86a4SJeremy Kemp 
1749*6fee86a4SJeremy Kemp #if defined(cl_ext_image_requirements_info)
1750*6fee86a4SJeremy Kemp CL_HPP_PARAM_NAME_CL_IMAGE_REQUIREMENTS_EXT(CL_HPP_DECLARE_PARAM_TRAITS_)
1751*6fee86a4SJeremy Kemp #endif // cl_ext_image_requirements_info
1752*6fee86a4SJeremy Kemp 
1753*6fee86a4SJeremy Kemp #if defined(cl_ext_image_from_buffer)
1754*6fee86a4SJeremy Kemp CL_HPP_PARAM_NAME_CL_IMAGE_REQUIREMENTS_SLICE_PITCH_ALIGNMENT_EXT(CL_HPP_DECLARE_PARAM_TRAITS_)
1755*6fee86a4SJeremy Kemp #endif // cl_ext_image_from_buffer
1756*6fee86a4SJeremy Kemp 
1757*6fee86a4SJeremy Kemp #ifdef CL_PLATFORM_ICD_SUFFIX_KHR
1758*6fee86a4SJeremy Kemp CL_HPP_DECLARE_PARAM_TRAITS_(cl_platform_info, CL_PLATFORM_ICD_SUFFIX_KHR, string)
1759*6fee86a4SJeremy Kemp #endif
1760*6fee86a4SJeremy Kemp 
1761*6fee86a4SJeremy Kemp #ifdef CL_DEVICE_PROFILING_TIMER_OFFSET_AMD
1762*6fee86a4SJeremy Kemp CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_PROFILING_TIMER_OFFSET_AMD, cl_ulong)
1763*6fee86a4SJeremy Kemp #endif
1764*6fee86a4SJeremy Kemp #ifdef CL_DEVICE_GLOBAL_FREE_MEMORY_AMD
1765*6fee86a4SJeremy Kemp CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_GLOBAL_FREE_MEMORY_AMD, vector<size_type>)
1766*6fee86a4SJeremy Kemp #endif
1767*6fee86a4SJeremy Kemp #ifdef CL_DEVICE_SIMD_PER_COMPUTE_UNIT_AMD
1768*6fee86a4SJeremy Kemp CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_SIMD_PER_COMPUTE_UNIT_AMD, cl_uint)
1769*6fee86a4SJeremy Kemp #endif
1770*6fee86a4SJeremy Kemp #ifdef CL_DEVICE_SIMD_WIDTH_AMD
1771*6fee86a4SJeremy Kemp CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_SIMD_WIDTH_AMD, cl_uint)
1772*6fee86a4SJeremy Kemp #endif
1773*6fee86a4SJeremy Kemp #ifdef CL_DEVICE_SIMD_INSTRUCTION_WIDTH_AMD
1774*6fee86a4SJeremy Kemp CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_SIMD_INSTRUCTION_WIDTH_AMD, cl_uint)
1775*6fee86a4SJeremy Kemp #endif
1776*6fee86a4SJeremy Kemp #ifdef CL_DEVICE_WAVEFRONT_WIDTH_AMD
1777*6fee86a4SJeremy Kemp CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_WAVEFRONT_WIDTH_AMD, cl_uint)
1778*6fee86a4SJeremy Kemp #endif
1779*6fee86a4SJeremy Kemp #ifdef CL_DEVICE_GLOBAL_MEM_CHANNELS_AMD
1780*6fee86a4SJeremy Kemp CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_GLOBAL_MEM_CHANNELS_AMD, cl_uint)
1781*6fee86a4SJeremy Kemp #endif
1782*6fee86a4SJeremy Kemp #ifdef CL_DEVICE_GLOBAL_MEM_CHANNEL_BANKS_AMD
1783*6fee86a4SJeremy Kemp CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_GLOBAL_MEM_CHANNEL_BANKS_AMD, cl_uint)
1784*6fee86a4SJeremy Kemp #endif
1785*6fee86a4SJeremy Kemp #ifdef CL_DEVICE_GLOBAL_MEM_CHANNEL_BANK_WIDTH_AMD
1786*6fee86a4SJeremy Kemp CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_GLOBAL_MEM_CHANNEL_BANK_WIDTH_AMD, cl_uint)
1787*6fee86a4SJeremy Kemp #endif
1788*6fee86a4SJeremy Kemp #ifdef CL_DEVICE_LOCAL_MEM_SIZE_PER_COMPUTE_UNIT_AMD
1789*6fee86a4SJeremy Kemp CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_LOCAL_MEM_SIZE_PER_COMPUTE_UNIT_AMD, cl_uint)
1790*6fee86a4SJeremy Kemp #endif
1791*6fee86a4SJeremy Kemp #ifdef CL_DEVICE_LOCAL_MEM_BANKS_AMD
1792*6fee86a4SJeremy Kemp CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_LOCAL_MEM_BANKS_AMD, cl_uint)
1793*6fee86a4SJeremy Kemp #endif
1794*6fee86a4SJeremy Kemp #ifdef CL_DEVICE_BOARD_NAME_AMD
1795*6fee86a4SJeremy Kemp CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_BOARD_NAME_AMD, string)
1796*6fee86a4SJeremy Kemp #endif
1797*6fee86a4SJeremy Kemp 
1798*6fee86a4SJeremy Kemp #ifdef CL_DEVICE_COMPUTE_UNITS_BITFIELD_ARM
1799*6fee86a4SJeremy Kemp CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_COMPUTE_UNITS_BITFIELD_ARM, cl_ulong)
1800*6fee86a4SJeremy Kemp #endif
1801*6fee86a4SJeremy Kemp #ifdef CL_DEVICE_JOB_SLOTS_ARM
1802*6fee86a4SJeremy Kemp CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_JOB_SLOTS_ARM, cl_uint)
1803*6fee86a4SJeremy Kemp #endif
1804*6fee86a4SJeremy Kemp #ifdef CL_DEVICE_SCHEDULING_CONTROLS_CAPABILITIES_ARM
1805*6fee86a4SJeremy Kemp CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_SCHEDULING_CONTROLS_CAPABILITIES_ARM, cl_bitfield)
1806*6fee86a4SJeremy Kemp #endif
1807*6fee86a4SJeremy Kemp #ifdef CL_DEVICE_SUPPORTED_REGISTER_ALLOCATIONS_ARM
1808*6fee86a4SJeremy Kemp CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_SUPPORTED_REGISTER_ALLOCATIONS_ARM, vector<cl_uint>)
1809*6fee86a4SJeremy Kemp #endif
1810*6fee86a4SJeremy Kemp #ifdef CL_DEVICE_MAX_WARP_COUNT_ARM
1811*6fee86a4SJeremy Kemp CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_MAX_WARP_COUNT_ARM, cl_uint)
1812*6fee86a4SJeremy Kemp #endif
1813*6fee86a4SJeremy Kemp #ifdef CL_KERNEL_MAX_WARP_COUNT_ARM
1814*6fee86a4SJeremy Kemp CL_HPP_DECLARE_PARAM_TRAITS_(cl_kernel_info, CL_KERNEL_MAX_WARP_COUNT_ARM, cl_uint)
1815*6fee86a4SJeremy Kemp #endif
1816*6fee86a4SJeremy Kemp #ifdef CL_KERNEL_EXEC_INFO_WORKGROUP_BATCH_SIZE_ARM
1817*6fee86a4SJeremy Kemp CL_HPP_DECLARE_PARAM_TRAITS_(cl_kernel_exec_info, CL_KERNEL_EXEC_INFO_WORKGROUP_BATCH_SIZE_ARM, cl_uint)
1818*6fee86a4SJeremy Kemp #endif
1819*6fee86a4SJeremy Kemp #ifdef CL_KERNEL_EXEC_INFO_WORKGROUP_BATCH_SIZE_MODIFIER_ARM
1820*6fee86a4SJeremy Kemp CL_HPP_DECLARE_PARAM_TRAITS_(cl_kernel_exec_info, CL_KERNEL_EXEC_INFO_WORKGROUP_BATCH_SIZE_MODIFIER_ARM, cl_int)
1821*6fee86a4SJeremy Kemp #endif
1822*6fee86a4SJeremy Kemp #ifdef CL_KERNEL_EXEC_INFO_WARP_COUNT_LIMIT_ARM
1823*6fee86a4SJeremy Kemp CL_HPP_DECLARE_PARAM_TRAITS_(cl_kernel_exec_info, CL_KERNEL_EXEC_INFO_WARP_COUNT_LIMIT_ARM, cl_uint)
1824*6fee86a4SJeremy Kemp #endif
1825*6fee86a4SJeremy Kemp #ifdef CL_KERNEL_EXEC_INFO_COMPUTE_UNIT_MAX_QUEUED_BATCHES_ARM
1826*6fee86a4SJeremy Kemp CL_HPP_DECLARE_PARAM_TRAITS_(cl_kernel_exec_info, CL_KERNEL_EXEC_INFO_COMPUTE_UNIT_MAX_QUEUED_BATCHES_ARM, cl_uint)
1827*6fee86a4SJeremy Kemp #endif
1828*6fee86a4SJeremy Kemp 
1829*6fee86a4SJeremy Kemp #ifdef CL_DEVICE_COMPUTE_CAPABILITY_MAJOR_NV
1830*6fee86a4SJeremy Kemp CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_COMPUTE_CAPABILITY_MAJOR_NV, cl_uint)
1831*6fee86a4SJeremy Kemp #endif
1832*6fee86a4SJeremy Kemp #ifdef CL_DEVICE_COMPUTE_CAPABILITY_MINOR_NV
1833*6fee86a4SJeremy Kemp CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_COMPUTE_CAPABILITY_MINOR_NV, cl_uint)
1834*6fee86a4SJeremy Kemp #endif
1835*6fee86a4SJeremy Kemp #ifdef CL_DEVICE_REGISTERS_PER_BLOCK_NV
1836*6fee86a4SJeremy Kemp CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_REGISTERS_PER_BLOCK_NV, cl_uint)
1837*6fee86a4SJeremy Kemp #endif
1838*6fee86a4SJeremy Kemp #ifdef CL_DEVICE_WARP_SIZE_NV
1839*6fee86a4SJeremy Kemp CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_WARP_SIZE_NV, cl_uint)
1840*6fee86a4SJeremy Kemp #endif
1841*6fee86a4SJeremy Kemp #ifdef CL_DEVICE_GPU_OVERLAP_NV
1842*6fee86a4SJeremy Kemp CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_GPU_OVERLAP_NV, cl_bool)
1843*6fee86a4SJeremy Kemp #endif
1844*6fee86a4SJeremy Kemp #ifdef CL_DEVICE_KERNEL_EXEC_TIMEOUT_NV
1845*6fee86a4SJeremy Kemp CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_KERNEL_EXEC_TIMEOUT_NV, cl_bool)
1846*6fee86a4SJeremy Kemp #endif
1847*6fee86a4SJeremy Kemp #ifdef CL_DEVICE_INTEGRATED_MEMORY_NV
1848*6fee86a4SJeremy Kemp CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_INTEGRATED_MEMORY_NV, cl_bool)
1849*6fee86a4SJeremy Kemp #endif
1850*6fee86a4SJeremy Kemp 
1851*6fee86a4SJeremy Kemp #if defined(cl_khr_command_buffer)
1852*6fee86a4SJeremy Kemp CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_COMMAND_BUFFER_CAPABILITIES_KHR, cl_device_command_buffer_capabilities_khr)
1853*6fee86a4SJeremy Kemp CL_HPP_DECLARE_PARAM_TRAITS_(cl_device_info, CL_DEVICE_COMMAND_BUFFER_REQUIRED_QUEUE_PROPERTIES_KHR, cl_command_buffer_properties_khr)
1854*6fee86a4SJeremy Kemp CL_HPP_DECLARE_PARAM_TRAITS_(cl_command_buffer_info_khr, CL_COMMAND_BUFFER_QUEUES_KHR, cl::vector<CommandQueue>)
1855*6fee86a4SJeremy Kemp CL_HPP_DECLARE_PARAM_TRAITS_(cl_command_buffer_info_khr, CL_COMMAND_BUFFER_NUM_QUEUES_KHR, cl_uint)
1856*6fee86a4SJeremy Kemp CL_HPP_DECLARE_PARAM_TRAITS_(cl_command_buffer_info_khr, CL_COMMAND_BUFFER_REFERENCE_COUNT_KHR, cl_uint)
1857*6fee86a4SJeremy Kemp CL_HPP_DECLARE_PARAM_TRAITS_(cl_command_buffer_info_khr, CL_COMMAND_BUFFER_STATE_KHR, cl_command_buffer_state_khr)
1858*6fee86a4SJeremy Kemp CL_HPP_DECLARE_PARAM_TRAITS_(cl_command_buffer_info_khr, CL_COMMAND_BUFFER_PROPERTIES_ARRAY_KHR, cl::vector<cl_command_buffer_properties_khr>)
1859*6fee86a4SJeremy Kemp #endif /* cl_khr_command_buffer */
1860*6fee86a4SJeremy Kemp 
1861*6fee86a4SJeremy Kemp #if defined(cl_khr_command_buffer_mutable_dispatch)
1862*6fee86a4SJeremy Kemp CL_HPP_DECLARE_PARAM_TRAITS_(cl_mutable_command_info_khr, CL_MUTABLE_COMMAND_COMMAND_QUEUE_KHR, CommandQueue)
1863*6fee86a4SJeremy Kemp CL_HPP_DECLARE_PARAM_TRAITS_(cl_mutable_command_info_khr, CL_MUTABLE_COMMAND_COMMAND_BUFFER_KHR, CommandBufferKhr)
1864*6fee86a4SJeremy Kemp CL_HPP_DECLARE_PARAM_TRAITS_(cl_mutable_command_info_khr, CL_MUTABLE_COMMAND_COMMAND_TYPE_KHR, cl_command_type)
1865*6fee86a4SJeremy Kemp CL_HPP_DECLARE_PARAM_TRAITS_(cl_mutable_command_info_khr, CL_MUTABLE_DISPATCH_PROPERTIES_ARRAY_KHR, cl::vector<cl_ndrange_kernel_command_properties_khr>)
1866*6fee86a4SJeremy Kemp CL_HPP_DECLARE_PARAM_TRAITS_(cl_mutable_command_info_khr, CL_MUTABLE_DISPATCH_KERNEL_KHR, cl_kernel)
1867*6fee86a4SJeremy Kemp CL_HPP_DECLARE_PARAM_TRAITS_(cl_mutable_command_info_khr, CL_MUTABLE_DISPATCH_DIMENSIONS_KHR, cl_uint)
1868*6fee86a4SJeremy Kemp CL_HPP_DECLARE_PARAM_TRAITS_(cl_mutable_command_info_khr, CL_MUTABLE_DISPATCH_GLOBAL_WORK_OFFSET_KHR, cl::vector<size_type>)
1869*6fee86a4SJeremy Kemp CL_HPP_DECLARE_PARAM_TRAITS_(cl_mutable_command_info_khr, CL_MUTABLE_DISPATCH_GLOBAL_WORK_SIZE_KHR, cl::vector<size_type>)
1870*6fee86a4SJeremy Kemp CL_HPP_DECLARE_PARAM_TRAITS_(cl_mutable_command_info_khr, CL_MUTABLE_DISPATCH_LOCAL_WORK_SIZE_KHR, cl::vector<size_type>)
1871*6fee86a4SJeremy Kemp #endif /* cl_khr_command_buffer_mutable_dispatch */
1872*6fee86a4SJeremy Kemp 
1873*6fee86a4SJeremy Kemp // Convenience functions
1874*6fee86a4SJeremy Kemp 
1875*6fee86a4SJeremy Kemp template <typename Func, typename T>
1876*6fee86a4SJeremy Kemp inline cl_int
1877*6fee86a4SJeremy Kemp getInfo(Func f, cl_uint name, T* param)
1878*6fee86a4SJeremy Kemp {
1879*6fee86a4SJeremy Kemp     return getInfoHelper(f, name, param, 0);
1880*6fee86a4SJeremy Kemp }
1881*6fee86a4SJeremy Kemp 
1882*6fee86a4SJeremy Kemp template <typename Func, typename Arg0>
1883*6fee86a4SJeremy Kemp struct GetInfoFunctor0
1884*6fee86a4SJeremy Kemp {
1885*6fee86a4SJeremy Kemp     Func f_; const Arg0& arg0_;
operator ()cl::detail::GetInfoFunctor01886*6fee86a4SJeremy Kemp     cl_int operator ()(
1887*6fee86a4SJeremy Kemp         cl_uint param, size_type size, void* value, size_type* size_ret)
1888*6fee86a4SJeremy Kemp     { return f_(arg0_, param, size, value, size_ret); }
1889*6fee86a4SJeremy Kemp };
1890*6fee86a4SJeremy Kemp 
1891*6fee86a4SJeremy Kemp template <typename Func, typename Arg0, typename Arg1>
1892*6fee86a4SJeremy Kemp struct GetInfoFunctor1
1893*6fee86a4SJeremy Kemp {
1894*6fee86a4SJeremy Kemp     Func f_; const Arg0& arg0_; const Arg1& arg1_;
operator ()cl::detail::GetInfoFunctor11895*6fee86a4SJeremy Kemp     cl_int operator ()(
1896*6fee86a4SJeremy Kemp         cl_uint param, size_type size, void* value, size_type* size_ret)
1897*6fee86a4SJeremy Kemp     { return f_(arg0_, arg1_, param, size, value, size_ret); }
1898*6fee86a4SJeremy Kemp };
1899*6fee86a4SJeremy Kemp 
1900*6fee86a4SJeremy Kemp template <typename Func, typename Arg0, typename T>
1901*6fee86a4SJeremy Kemp inline cl_int
getInfo(Func f,const Arg0 & arg0,cl_uint name,T * param)1902*6fee86a4SJeremy Kemp getInfo(Func f, const Arg0& arg0, cl_uint name, T* param)
1903*6fee86a4SJeremy Kemp {
1904*6fee86a4SJeremy Kemp     GetInfoFunctor0<Func, Arg0> f0 = { f, arg0 };
1905*6fee86a4SJeremy Kemp     return getInfoHelper(f0, name, param, 0);
1906*6fee86a4SJeremy Kemp }
1907*6fee86a4SJeremy Kemp 
1908*6fee86a4SJeremy Kemp template <typename Func, typename Arg0, typename Arg1, typename T>
1909*6fee86a4SJeremy Kemp inline cl_int
getInfo(Func f,const Arg0 & arg0,const Arg1 & arg1,cl_uint name,T * param)1910*6fee86a4SJeremy Kemp getInfo(Func f, const Arg0& arg0, const Arg1& arg1, cl_uint name, T* param)
1911*6fee86a4SJeremy Kemp {
1912*6fee86a4SJeremy Kemp     GetInfoFunctor1<Func, Arg0, Arg1> f0 = { f, arg0, arg1 };
1913*6fee86a4SJeremy Kemp     return getInfoHelper(f0, name, param, 0);
1914*6fee86a4SJeremy Kemp }
1915*6fee86a4SJeremy Kemp 
1916*6fee86a4SJeremy Kemp 
1917*6fee86a4SJeremy Kemp template<typename T>
1918*6fee86a4SJeremy Kemp struct ReferenceHandler
1919*6fee86a4SJeremy Kemp { };
1920*6fee86a4SJeremy Kemp 
1921*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 120
1922*6fee86a4SJeremy Kemp /**
1923*6fee86a4SJeremy Kemp  * OpenCL 1.2 devices do have retain/release.
1924*6fee86a4SJeremy Kemp  */
1925*6fee86a4SJeremy Kemp template <>
1926*6fee86a4SJeremy Kemp struct ReferenceHandler<cl_device_id>
1927*6fee86a4SJeremy Kemp {
1928*6fee86a4SJeremy Kemp     /**
1929*6fee86a4SJeremy Kemp      * Retain the device.
1930*6fee86a4SJeremy Kemp      * \param device A valid device created using createSubDevices
1931*6fee86a4SJeremy Kemp      * \return
1932*6fee86a4SJeremy Kemp      *   CL_SUCCESS if the function executed successfully.
1933*6fee86a4SJeremy Kemp      *   CL_INVALID_DEVICE if device was not a valid subdevice
1934*6fee86a4SJeremy Kemp      *   CL_OUT_OF_RESOURCES
1935*6fee86a4SJeremy Kemp      *   CL_OUT_OF_HOST_MEMORY
1936*6fee86a4SJeremy Kemp      */
retaincl::detail::ReferenceHandler1937*6fee86a4SJeremy Kemp     static cl_int retain(cl_device_id device)
1938*6fee86a4SJeremy Kemp     { return ::clRetainDevice(device); }
1939*6fee86a4SJeremy Kemp     /**
1940*6fee86a4SJeremy Kemp      * Retain the device.
1941*6fee86a4SJeremy Kemp      * \param device A valid device created using createSubDevices
1942*6fee86a4SJeremy Kemp      * \return
1943*6fee86a4SJeremy Kemp      *   CL_SUCCESS if the function executed successfully.
1944*6fee86a4SJeremy Kemp      *   CL_INVALID_DEVICE if device was not a valid subdevice
1945*6fee86a4SJeremy Kemp      *   CL_OUT_OF_RESOURCES
1946*6fee86a4SJeremy Kemp      *   CL_OUT_OF_HOST_MEMORY
1947*6fee86a4SJeremy Kemp      */
releasecl::detail::ReferenceHandler1948*6fee86a4SJeremy Kemp     static cl_int release(cl_device_id device)
1949*6fee86a4SJeremy Kemp     { return ::clReleaseDevice(device); }
1950*6fee86a4SJeremy Kemp };
1951*6fee86a4SJeremy Kemp #else // CL_HPP_TARGET_OPENCL_VERSION >= 120
1952*6fee86a4SJeremy Kemp /**
1953*6fee86a4SJeremy Kemp  * OpenCL 1.1 devices do not have retain/release.
1954*6fee86a4SJeremy Kemp  */
1955*6fee86a4SJeremy Kemp template <>
1956*6fee86a4SJeremy Kemp struct ReferenceHandler<cl_device_id>
1957*6fee86a4SJeremy Kemp {
1958*6fee86a4SJeremy Kemp     // cl_device_id does not have retain().
retaincl::detail::ReferenceHandler1959*6fee86a4SJeremy Kemp     static cl_int retain(cl_device_id)
1960*6fee86a4SJeremy Kemp     { return CL_SUCCESS; }
1961*6fee86a4SJeremy Kemp     // cl_device_id does not have release().
releasecl::detail::ReferenceHandler1962*6fee86a4SJeremy Kemp     static cl_int release(cl_device_id)
1963*6fee86a4SJeremy Kemp     { return CL_SUCCESS; }
1964*6fee86a4SJeremy Kemp };
1965*6fee86a4SJeremy Kemp #endif // ! (CL_HPP_TARGET_OPENCL_VERSION >= 120)
1966*6fee86a4SJeremy Kemp 
1967*6fee86a4SJeremy Kemp template <>
1968*6fee86a4SJeremy Kemp struct ReferenceHandler<cl_platform_id>
1969*6fee86a4SJeremy Kemp {
1970*6fee86a4SJeremy Kemp     // cl_platform_id does not have retain().
retaincl::detail::ReferenceHandler1971*6fee86a4SJeremy Kemp     static cl_int retain(cl_platform_id)
1972*6fee86a4SJeremy Kemp     { return CL_SUCCESS; }
1973*6fee86a4SJeremy Kemp     // cl_platform_id does not have release().
releasecl::detail::ReferenceHandler1974*6fee86a4SJeremy Kemp     static cl_int release(cl_platform_id)
1975*6fee86a4SJeremy Kemp     { return CL_SUCCESS; }
1976*6fee86a4SJeremy Kemp };
1977*6fee86a4SJeremy Kemp 
1978*6fee86a4SJeremy Kemp template <>
1979*6fee86a4SJeremy Kemp struct ReferenceHandler<cl_context>
1980*6fee86a4SJeremy Kemp {
retaincl::detail::ReferenceHandler1981*6fee86a4SJeremy Kemp     static cl_int retain(cl_context context)
1982*6fee86a4SJeremy Kemp     { return ::clRetainContext(context); }
releasecl::detail::ReferenceHandler1983*6fee86a4SJeremy Kemp     static cl_int release(cl_context context)
1984*6fee86a4SJeremy Kemp     { return ::clReleaseContext(context); }
1985*6fee86a4SJeremy Kemp };
1986*6fee86a4SJeremy Kemp 
1987*6fee86a4SJeremy Kemp template <>
1988*6fee86a4SJeremy Kemp struct ReferenceHandler<cl_command_queue>
1989*6fee86a4SJeremy Kemp {
retaincl::detail::ReferenceHandler1990*6fee86a4SJeremy Kemp     static cl_int retain(cl_command_queue queue)
1991*6fee86a4SJeremy Kemp     { return ::clRetainCommandQueue(queue); }
releasecl::detail::ReferenceHandler1992*6fee86a4SJeremy Kemp     static cl_int release(cl_command_queue queue)
1993*6fee86a4SJeremy Kemp     { return ::clReleaseCommandQueue(queue); }
1994*6fee86a4SJeremy Kemp };
1995*6fee86a4SJeremy Kemp 
1996*6fee86a4SJeremy Kemp template <>
1997*6fee86a4SJeremy Kemp struct ReferenceHandler<cl_mem>
1998*6fee86a4SJeremy Kemp {
retaincl::detail::ReferenceHandler1999*6fee86a4SJeremy Kemp     static cl_int retain(cl_mem memory)
2000*6fee86a4SJeremy Kemp     { return ::clRetainMemObject(memory); }
releasecl::detail::ReferenceHandler2001*6fee86a4SJeremy Kemp     static cl_int release(cl_mem memory)
2002*6fee86a4SJeremy Kemp     { return ::clReleaseMemObject(memory); }
2003*6fee86a4SJeremy Kemp };
2004*6fee86a4SJeremy Kemp 
2005*6fee86a4SJeremy Kemp template <>
2006*6fee86a4SJeremy Kemp struct ReferenceHandler<cl_sampler>
2007*6fee86a4SJeremy Kemp {
retaincl::detail::ReferenceHandler2008*6fee86a4SJeremy Kemp     static cl_int retain(cl_sampler sampler)
2009*6fee86a4SJeremy Kemp     { return ::clRetainSampler(sampler); }
releasecl::detail::ReferenceHandler2010*6fee86a4SJeremy Kemp     static cl_int release(cl_sampler sampler)
2011*6fee86a4SJeremy Kemp     { return ::clReleaseSampler(sampler); }
2012*6fee86a4SJeremy Kemp };
2013*6fee86a4SJeremy Kemp 
2014*6fee86a4SJeremy Kemp template <>
2015*6fee86a4SJeremy Kemp struct ReferenceHandler<cl_program>
2016*6fee86a4SJeremy Kemp {
retaincl::detail::ReferenceHandler2017*6fee86a4SJeremy Kemp     static cl_int retain(cl_program program)
2018*6fee86a4SJeremy Kemp     { return ::clRetainProgram(program); }
releasecl::detail::ReferenceHandler2019*6fee86a4SJeremy Kemp     static cl_int release(cl_program program)
2020*6fee86a4SJeremy Kemp     { return ::clReleaseProgram(program); }
2021*6fee86a4SJeremy Kemp };
2022*6fee86a4SJeremy Kemp 
2023*6fee86a4SJeremy Kemp template <>
2024*6fee86a4SJeremy Kemp struct ReferenceHandler<cl_kernel>
2025*6fee86a4SJeremy Kemp {
retaincl::detail::ReferenceHandler2026*6fee86a4SJeremy Kemp     static cl_int retain(cl_kernel kernel)
2027*6fee86a4SJeremy Kemp     { return ::clRetainKernel(kernel); }
releasecl::detail::ReferenceHandler2028*6fee86a4SJeremy Kemp     static cl_int release(cl_kernel kernel)
2029*6fee86a4SJeremy Kemp     { return ::clReleaseKernel(kernel); }
2030*6fee86a4SJeremy Kemp };
2031*6fee86a4SJeremy Kemp 
2032*6fee86a4SJeremy Kemp template <>
2033*6fee86a4SJeremy Kemp struct ReferenceHandler<cl_event>
2034*6fee86a4SJeremy Kemp {
retaincl::detail::ReferenceHandler2035*6fee86a4SJeremy Kemp     static cl_int retain(cl_event event)
2036*6fee86a4SJeremy Kemp     { return ::clRetainEvent(event); }
releasecl::detail::ReferenceHandler2037*6fee86a4SJeremy Kemp     static cl_int release(cl_event event)
2038*6fee86a4SJeremy Kemp     { return ::clReleaseEvent(event); }
2039*6fee86a4SJeremy Kemp };
2040*6fee86a4SJeremy Kemp 
2041*6fee86a4SJeremy Kemp #ifdef cl_khr_semaphore
2042*6fee86a4SJeremy Kemp template <>
2043*6fee86a4SJeremy Kemp struct ReferenceHandler<cl_semaphore_khr>
2044*6fee86a4SJeremy Kemp {
retaincl::detail::ReferenceHandler2045*6fee86a4SJeremy Kemp     static cl_int retain(cl_semaphore_khr semaphore)
2046*6fee86a4SJeremy Kemp     {
2047*6fee86a4SJeremy Kemp         if (pfn_clRetainSemaphoreKHR != nullptr) {
2048*6fee86a4SJeremy Kemp             return pfn_clRetainSemaphoreKHR(semaphore);
2049*6fee86a4SJeremy Kemp         }
2050*6fee86a4SJeremy Kemp 
2051*6fee86a4SJeremy Kemp         return CL_INVALID_OPERATION;
2052*6fee86a4SJeremy Kemp     }
2053*6fee86a4SJeremy Kemp 
releasecl::detail::ReferenceHandler2054*6fee86a4SJeremy Kemp     static cl_int release(cl_semaphore_khr semaphore)
2055*6fee86a4SJeremy Kemp     {
2056*6fee86a4SJeremy Kemp         if (pfn_clReleaseSemaphoreKHR != nullptr) {
2057*6fee86a4SJeremy Kemp             return pfn_clReleaseSemaphoreKHR(semaphore);
2058*6fee86a4SJeremy Kemp         }
2059*6fee86a4SJeremy Kemp 
2060*6fee86a4SJeremy Kemp         return CL_INVALID_OPERATION;
2061*6fee86a4SJeremy Kemp     }
2062*6fee86a4SJeremy Kemp };
2063*6fee86a4SJeremy Kemp #endif // cl_khr_semaphore
2064*6fee86a4SJeremy Kemp #if defined(cl_khr_command_buffer)
2065*6fee86a4SJeremy Kemp template <>
2066*6fee86a4SJeremy Kemp struct ReferenceHandler<cl_command_buffer_khr>
2067*6fee86a4SJeremy Kemp {
retaincl::detail::ReferenceHandler2068*6fee86a4SJeremy Kemp     static cl_int retain(cl_command_buffer_khr cmdBufferKhr)
2069*6fee86a4SJeremy Kemp     {
2070*6fee86a4SJeremy Kemp         if (pfn_clRetainCommandBufferKHR == nullptr) {
2071*6fee86a4SJeremy Kemp             return detail::errHandler(CL_INVALID_OPERATION, __RETAIN_COMMAND_BUFFER_KHR_ERR);
2072*6fee86a4SJeremy Kemp         }
2073*6fee86a4SJeremy Kemp         return pfn_clRetainCommandBufferKHR(cmdBufferKhr);
2074*6fee86a4SJeremy Kemp     }
2075*6fee86a4SJeremy Kemp 
releasecl::detail::ReferenceHandler2076*6fee86a4SJeremy Kemp     static cl_int release(cl_command_buffer_khr cmdBufferKhr)
2077*6fee86a4SJeremy Kemp     {
2078*6fee86a4SJeremy Kemp         if (pfn_clReleaseCommandBufferKHR == nullptr) {
2079*6fee86a4SJeremy Kemp             return detail::errHandler(CL_INVALID_OPERATION, __RELEASE_COMMAND_BUFFER_KHR_ERR);
2080*6fee86a4SJeremy Kemp         }
2081*6fee86a4SJeremy Kemp         return pfn_clReleaseCommandBufferKHR(cmdBufferKhr);
2082*6fee86a4SJeremy Kemp     }
2083*6fee86a4SJeremy Kemp };
2084*6fee86a4SJeremy Kemp 
2085*6fee86a4SJeremy Kemp template <>
2086*6fee86a4SJeremy Kemp struct ReferenceHandler<cl_mutable_command_khr>
2087*6fee86a4SJeremy Kemp {
2088*6fee86a4SJeremy Kemp     // cl_mutable_command_khr does not have retain().
retaincl::detail::ReferenceHandler2089*6fee86a4SJeremy Kemp     static cl_int retain(cl_mutable_command_khr)
2090*6fee86a4SJeremy Kemp     { return CL_SUCCESS; }
2091*6fee86a4SJeremy Kemp     // cl_mutable_command_khr does not have release().
releasecl::detail::ReferenceHandler2092*6fee86a4SJeremy Kemp     static cl_int release(cl_mutable_command_khr)
2093*6fee86a4SJeremy Kemp     { return CL_SUCCESS; }
2094*6fee86a4SJeremy Kemp };
2095*6fee86a4SJeremy Kemp #endif // cl_khr_command_buffer
2096*6fee86a4SJeremy Kemp 
2097*6fee86a4SJeremy Kemp 
2098*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 120 && CL_HPP_MINIMUM_OPENCL_VERSION < 200
2099*6fee86a4SJeremy Kemp // Extracts version number with major in the upper 16 bits, minor in the lower 16
getVersion(const vector<char> & versionInfo)2100*6fee86a4SJeremy Kemp static cl_uint getVersion(const vector<char> &versionInfo)
2101*6fee86a4SJeremy Kemp {
2102*6fee86a4SJeremy Kemp     int highVersion = 0;
2103*6fee86a4SJeremy Kemp     int lowVersion = 0;
2104*6fee86a4SJeremy Kemp     int index = 7;
2105*6fee86a4SJeremy Kemp     while(versionInfo[index] != '.' ) {
2106*6fee86a4SJeremy Kemp         highVersion *= 10;
2107*6fee86a4SJeremy Kemp         highVersion += versionInfo[index]-'0';
2108*6fee86a4SJeremy Kemp         ++index;
2109*6fee86a4SJeremy Kemp     }
2110*6fee86a4SJeremy Kemp     ++index;
2111*6fee86a4SJeremy Kemp     while(versionInfo[index] != ' ' &&  versionInfo[index] != '\0') {
2112*6fee86a4SJeremy Kemp         lowVersion *= 10;
2113*6fee86a4SJeremy Kemp         lowVersion += versionInfo[index]-'0';
2114*6fee86a4SJeremy Kemp         ++index;
2115*6fee86a4SJeremy Kemp     }
2116*6fee86a4SJeremy Kemp     return (highVersion << 16) | lowVersion;
2117*6fee86a4SJeremy Kemp }
2118*6fee86a4SJeremy Kemp 
getPlatformVersion(cl_platform_id platform)2119*6fee86a4SJeremy Kemp static cl_uint getPlatformVersion(cl_platform_id platform)
2120*6fee86a4SJeremy Kemp {
2121*6fee86a4SJeremy Kemp     size_type size = 0;
2122*6fee86a4SJeremy Kemp     clGetPlatformInfo(platform, CL_PLATFORM_VERSION, 0, nullptr, &size);
2123*6fee86a4SJeremy Kemp 
2124*6fee86a4SJeremy Kemp     vector<char> versionInfo(size);
2125*6fee86a4SJeremy Kemp     clGetPlatformInfo(platform, CL_PLATFORM_VERSION, size, versionInfo.data(), &size);
2126*6fee86a4SJeremy Kemp     return getVersion(versionInfo);
2127*6fee86a4SJeremy Kemp }
2128*6fee86a4SJeremy Kemp 
getDevicePlatformVersion(cl_device_id device)2129*6fee86a4SJeremy Kemp static cl_uint getDevicePlatformVersion(cl_device_id device)
2130*6fee86a4SJeremy Kemp {
2131*6fee86a4SJeremy Kemp     cl_platform_id platform;
2132*6fee86a4SJeremy Kemp     clGetDeviceInfo(device, CL_DEVICE_PLATFORM, sizeof(platform), &platform, nullptr);
2133*6fee86a4SJeremy Kemp     return getPlatformVersion(platform);
2134*6fee86a4SJeremy Kemp }
2135*6fee86a4SJeremy Kemp 
getContextPlatformVersion(cl_context context)2136*6fee86a4SJeremy Kemp static cl_uint getContextPlatformVersion(cl_context context)
2137*6fee86a4SJeremy Kemp {
2138*6fee86a4SJeremy Kemp     // The platform cannot be queried directly, so we first have to grab a
2139*6fee86a4SJeremy Kemp     // device and obtain its context
2140*6fee86a4SJeremy Kemp     size_type size = 0;
2141*6fee86a4SJeremy Kemp     clGetContextInfo(context, CL_CONTEXT_DEVICES, 0, nullptr, &size);
2142*6fee86a4SJeremy Kemp     if (size == 0)
2143*6fee86a4SJeremy Kemp         return 0;
2144*6fee86a4SJeremy Kemp     vector<cl_device_id> devices(size/sizeof(cl_device_id));
2145*6fee86a4SJeremy Kemp     clGetContextInfo(context, CL_CONTEXT_DEVICES, size, devices.data(), nullptr);
2146*6fee86a4SJeremy Kemp     return getDevicePlatformVersion(devices[0]);
2147*6fee86a4SJeremy Kemp }
2148*6fee86a4SJeremy Kemp #endif // CL_HPP_TARGET_OPENCL_VERSION >= 120 && CL_HPP_MINIMUM_OPENCL_VERSION < 200
2149*6fee86a4SJeremy Kemp 
2150*6fee86a4SJeremy Kemp template <typename T>
2151*6fee86a4SJeremy Kemp class Wrapper
2152*6fee86a4SJeremy Kemp {
2153*6fee86a4SJeremy Kemp public:
2154*6fee86a4SJeremy Kemp     typedef T cl_type;
2155*6fee86a4SJeremy Kemp 
2156*6fee86a4SJeremy Kemp protected:
2157*6fee86a4SJeremy Kemp     cl_type object_;
2158*6fee86a4SJeremy Kemp 
2159*6fee86a4SJeremy Kemp public:
Wrapper()2160*6fee86a4SJeremy Kemp     Wrapper() : object_(nullptr) { }
2161*6fee86a4SJeremy Kemp 
Wrapper(const cl_type & obj,bool retainObject)2162*6fee86a4SJeremy Kemp     Wrapper(const cl_type &obj, bool retainObject) : object_(obj)
2163*6fee86a4SJeremy Kemp     {
2164*6fee86a4SJeremy Kemp         if (retainObject) {
2165*6fee86a4SJeremy Kemp             detail::errHandler(retain(), __RETAIN_ERR);
2166*6fee86a4SJeremy Kemp         }
2167*6fee86a4SJeremy Kemp     }
2168*6fee86a4SJeremy Kemp 
~Wrapper()2169*6fee86a4SJeremy Kemp     ~Wrapper()
2170*6fee86a4SJeremy Kemp     {
2171*6fee86a4SJeremy Kemp         if (object_ != nullptr) { release(); }
2172*6fee86a4SJeremy Kemp     }
2173*6fee86a4SJeremy Kemp 
Wrapper(const Wrapper<cl_type> & rhs)2174*6fee86a4SJeremy Kemp     Wrapper(const Wrapper<cl_type>& rhs)
2175*6fee86a4SJeremy Kemp     {
2176*6fee86a4SJeremy Kemp         object_ = rhs.object_;
2177*6fee86a4SJeremy Kemp         detail::errHandler(retain(), __RETAIN_ERR);
2178*6fee86a4SJeremy Kemp     }
2179*6fee86a4SJeremy Kemp 
Wrapper(Wrapper<cl_type> && rhs)2180*6fee86a4SJeremy Kemp     Wrapper(Wrapper<cl_type>&& rhs) noexcept
2181*6fee86a4SJeremy Kemp     {
2182*6fee86a4SJeremy Kemp         object_ = rhs.object_;
2183*6fee86a4SJeremy Kemp         rhs.object_ = nullptr;
2184*6fee86a4SJeremy Kemp     }
2185*6fee86a4SJeremy Kemp 
operator =(const Wrapper<cl_type> & rhs)2186*6fee86a4SJeremy Kemp     Wrapper<cl_type>& operator = (const Wrapper<cl_type>& rhs)
2187*6fee86a4SJeremy Kemp     {
2188*6fee86a4SJeremy Kemp         if (this != &rhs) {
2189*6fee86a4SJeremy Kemp             detail::errHandler(release(), __RELEASE_ERR);
2190*6fee86a4SJeremy Kemp             object_ = rhs.object_;
2191*6fee86a4SJeremy Kemp             detail::errHandler(retain(), __RETAIN_ERR);
2192*6fee86a4SJeremy Kemp         }
2193*6fee86a4SJeremy Kemp         return *this;
2194*6fee86a4SJeremy Kemp     }
2195*6fee86a4SJeremy Kemp 
operator =(Wrapper<cl_type> && rhs)2196*6fee86a4SJeremy Kemp     Wrapper<cl_type>& operator = (Wrapper<cl_type>&& rhs)
2197*6fee86a4SJeremy Kemp     {
2198*6fee86a4SJeremy Kemp         if (this != &rhs) {
2199*6fee86a4SJeremy Kemp             detail::errHandler(release(), __RELEASE_ERR);
2200*6fee86a4SJeremy Kemp             object_ = rhs.object_;
2201*6fee86a4SJeremy Kemp             rhs.object_ = nullptr;
2202*6fee86a4SJeremy Kemp         }
2203*6fee86a4SJeremy Kemp         return *this;
2204*6fee86a4SJeremy Kemp     }
2205*6fee86a4SJeremy Kemp 
operator =(const cl_type & rhs)2206*6fee86a4SJeremy Kemp     Wrapper<cl_type>& operator = (const cl_type &rhs)
2207*6fee86a4SJeremy Kemp     {
2208*6fee86a4SJeremy Kemp         detail::errHandler(release(), __RELEASE_ERR);
2209*6fee86a4SJeremy Kemp         object_ = rhs;
2210*6fee86a4SJeremy Kemp         return *this;
2211*6fee86a4SJeremy Kemp     }
2212*6fee86a4SJeremy Kemp 
operator ()() const2213*6fee86a4SJeremy Kemp     const cl_type& operator ()() const { return object_; }
2214*6fee86a4SJeremy Kemp 
operator ()()2215*6fee86a4SJeremy Kemp     cl_type& operator ()() { return object_; }
2216*6fee86a4SJeremy Kemp 
get() const2217*6fee86a4SJeremy Kemp     cl_type get() const { return object_; }
2218*6fee86a4SJeremy Kemp 
2219*6fee86a4SJeremy Kemp protected:
2220*6fee86a4SJeremy Kemp     template<typename Func, typename U>
2221*6fee86a4SJeremy Kemp     friend inline cl_int getInfoHelper(Func, cl_uint, U*, int, typename U::cl_type);
2222*6fee86a4SJeremy Kemp 
retain() const2223*6fee86a4SJeremy Kemp     cl_int retain() const
2224*6fee86a4SJeremy Kemp     {
2225*6fee86a4SJeremy Kemp         if (object_ != nullptr) {
2226*6fee86a4SJeremy Kemp             return ReferenceHandler<cl_type>::retain(object_);
2227*6fee86a4SJeremy Kemp         }
2228*6fee86a4SJeremy Kemp         else {
2229*6fee86a4SJeremy Kemp             return CL_SUCCESS;
2230*6fee86a4SJeremy Kemp         }
2231*6fee86a4SJeremy Kemp     }
2232*6fee86a4SJeremy Kemp 
release() const2233*6fee86a4SJeremy Kemp     cl_int release() const
2234*6fee86a4SJeremy Kemp     {
2235*6fee86a4SJeremy Kemp         if (object_ != nullptr) {
2236*6fee86a4SJeremy Kemp             return ReferenceHandler<cl_type>::release(object_);
2237*6fee86a4SJeremy Kemp         }
2238*6fee86a4SJeremy Kemp         else {
2239*6fee86a4SJeremy Kemp             return CL_SUCCESS;
2240*6fee86a4SJeremy Kemp         }
2241*6fee86a4SJeremy Kemp     }
2242*6fee86a4SJeremy Kemp };
2243*6fee86a4SJeremy Kemp 
2244*6fee86a4SJeremy Kemp template <>
2245*6fee86a4SJeremy Kemp class Wrapper<cl_device_id>
2246*6fee86a4SJeremy Kemp {
2247*6fee86a4SJeremy Kemp public:
2248*6fee86a4SJeremy Kemp     typedef cl_device_id cl_type;
2249*6fee86a4SJeremy Kemp 
2250*6fee86a4SJeremy Kemp protected:
2251*6fee86a4SJeremy Kemp     cl_type object_;
2252*6fee86a4SJeremy Kemp     bool referenceCountable_;
2253*6fee86a4SJeremy Kemp 
isReferenceCountable(cl_device_id device)2254*6fee86a4SJeremy Kemp     static bool isReferenceCountable(cl_device_id device)
2255*6fee86a4SJeremy Kemp     {
2256*6fee86a4SJeremy Kemp         bool retVal = false;
2257*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 120
2258*6fee86a4SJeremy Kemp #if CL_HPP_MINIMUM_OPENCL_VERSION < 120
2259*6fee86a4SJeremy Kemp         if (device != nullptr) {
2260*6fee86a4SJeremy Kemp             int version = getDevicePlatformVersion(device);
2261*6fee86a4SJeremy Kemp             if(version > ((1 << 16) + 1)) {
2262*6fee86a4SJeremy Kemp                 retVal = true;
2263*6fee86a4SJeremy Kemp             }
2264*6fee86a4SJeremy Kemp         }
2265*6fee86a4SJeremy Kemp #else // CL_HPP_MINIMUM_OPENCL_VERSION < 120
2266*6fee86a4SJeremy Kemp         retVal = true;
2267*6fee86a4SJeremy Kemp #endif // CL_HPP_MINIMUM_OPENCL_VERSION < 120
2268*6fee86a4SJeremy Kemp #endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
2269*6fee86a4SJeremy Kemp         (void)device;
2270*6fee86a4SJeremy Kemp         return retVal;
2271*6fee86a4SJeremy Kemp     }
2272*6fee86a4SJeremy Kemp 
2273*6fee86a4SJeremy Kemp public:
Wrapper()2274*6fee86a4SJeremy Kemp     Wrapper() : object_(nullptr), referenceCountable_(false)
2275*6fee86a4SJeremy Kemp     {
2276*6fee86a4SJeremy Kemp     }
2277*6fee86a4SJeremy Kemp 
Wrapper(const cl_type & obj,bool retainObject)2278*6fee86a4SJeremy Kemp     Wrapper(const cl_type &obj, bool retainObject) :
2279*6fee86a4SJeremy Kemp         object_(obj),
2280*6fee86a4SJeremy Kemp         referenceCountable_(false)
2281*6fee86a4SJeremy Kemp     {
2282*6fee86a4SJeremy Kemp         referenceCountable_ = isReferenceCountable(obj);
2283*6fee86a4SJeremy Kemp 
2284*6fee86a4SJeremy Kemp         if (retainObject) {
2285*6fee86a4SJeremy Kemp             detail::errHandler(retain(), __RETAIN_ERR);
2286*6fee86a4SJeremy Kemp         }
2287*6fee86a4SJeremy Kemp     }
2288*6fee86a4SJeremy Kemp 
~Wrapper()2289*6fee86a4SJeremy Kemp     ~Wrapper()
2290*6fee86a4SJeremy Kemp     {
2291*6fee86a4SJeremy Kemp         release();
2292*6fee86a4SJeremy Kemp     }
2293*6fee86a4SJeremy Kemp 
Wrapper(const Wrapper<cl_type> & rhs)2294*6fee86a4SJeremy Kemp     Wrapper(const Wrapper<cl_type>& rhs)
2295*6fee86a4SJeremy Kemp     {
2296*6fee86a4SJeremy Kemp         object_ = rhs.object_;
2297*6fee86a4SJeremy Kemp         referenceCountable_ = isReferenceCountable(object_);
2298*6fee86a4SJeremy Kemp         detail::errHandler(retain(), __RETAIN_ERR);
2299*6fee86a4SJeremy Kemp     }
2300*6fee86a4SJeremy Kemp 
Wrapper(Wrapper<cl_type> && rhs)2301*6fee86a4SJeremy Kemp     Wrapper(Wrapper<cl_type>&& rhs) noexcept
2302*6fee86a4SJeremy Kemp     {
2303*6fee86a4SJeremy Kemp         object_ = rhs.object_;
2304*6fee86a4SJeremy Kemp         referenceCountable_ = rhs.referenceCountable_;
2305*6fee86a4SJeremy Kemp         rhs.object_ = nullptr;
2306*6fee86a4SJeremy Kemp         rhs.referenceCountable_ = false;
2307*6fee86a4SJeremy Kemp     }
2308*6fee86a4SJeremy Kemp 
operator =(const Wrapper<cl_type> & rhs)2309*6fee86a4SJeremy Kemp     Wrapper<cl_type>& operator = (const Wrapper<cl_type>& rhs)
2310*6fee86a4SJeremy Kemp     {
2311*6fee86a4SJeremy Kemp         if (this != &rhs) {
2312*6fee86a4SJeremy Kemp             detail::errHandler(release(), __RELEASE_ERR);
2313*6fee86a4SJeremy Kemp             object_ = rhs.object_;
2314*6fee86a4SJeremy Kemp             referenceCountable_ = rhs.referenceCountable_;
2315*6fee86a4SJeremy Kemp             detail::errHandler(retain(), __RETAIN_ERR);
2316*6fee86a4SJeremy Kemp         }
2317*6fee86a4SJeremy Kemp         return *this;
2318*6fee86a4SJeremy Kemp     }
2319*6fee86a4SJeremy Kemp 
operator =(Wrapper<cl_type> && rhs)2320*6fee86a4SJeremy Kemp     Wrapper<cl_type>& operator = (Wrapper<cl_type>&& rhs)
2321*6fee86a4SJeremy Kemp     {
2322*6fee86a4SJeremy Kemp         if (this != &rhs) {
2323*6fee86a4SJeremy Kemp             detail::errHandler(release(), __RELEASE_ERR);
2324*6fee86a4SJeremy Kemp             object_ = rhs.object_;
2325*6fee86a4SJeremy Kemp             referenceCountable_ = rhs.referenceCountable_;
2326*6fee86a4SJeremy Kemp             rhs.object_ = nullptr;
2327*6fee86a4SJeremy Kemp             rhs.referenceCountable_ = false;
2328*6fee86a4SJeremy Kemp         }
2329*6fee86a4SJeremy Kemp         return *this;
2330*6fee86a4SJeremy Kemp     }
2331*6fee86a4SJeremy Kemp 
operator =(const cl_type & rhs)2332*6fee86a4SJeremy Kemp     Wrapper<cl_type>& operator = (const cl_type &rhs)
2333*6fee86a4SJeremy Kemp     {
2334*6fee86a4SJeremy Kemp         detail::errHandler(release(), __RELEASE_ERR);
2335*6fee86a4SJeremy Kemp         object_ = rhs;
2336*6fee86a4SJeremy Kemp         referenceCountable_ = isReferenceCountable(object_);
2337*6fee86a4SJeremy Kemp         return *this;
2338*6fee86a4SJeremy Kemp     }
2339*6fee86a4SJeremy Kemp 
operator ()() const2340*6fee86a4SJeremy Kemp     const cl_type& operator ()() const { return object_; }
2341*6fee86a4SJeremy Kemp 
operator ()()2342*6fee86a4SJeremy Kemp     cl_type& operator ()() { return object_; }
2343*6fee86a4SJeremy Kemp 
get() const2344*6fee86a4SJeremy Kemp     cl_type get() const { return object_; }
2345*6fee86a4SJeremy Kemp 
2346*6fee86a4SJeremy Kemp protected:
2347*6fee86a4SJeremy Kemp     template<typename Func, typename U>
2348*6fee86a4SJeremy Kemp     friend inline cl_int getInfoHelper(Func, cl_uint, U*, int, typename U::cl_type);
2349*6fee86a4SJeremy Kemp 
2350*6fee86a4SJeremy Kemp     template<typename Func, typename U>
2351*6fee86a4SJeremy Kemp     friend inline cl_int getInfoHelper(Func, cl_uint, vector<U>*, int, typename U::cl_type);
2352*6fee86a4SJeremy Kemp 
retain() const2353*6fee86a4SJeremy Kemp     cl_int retain() const
2354*6fee86a4SJeremy Kemp     {
2355*6fee86a4SJeremy Kemp         if( object_ != nullptr && referenceCountable_ ) {
2356*6fee86a4SJeremy Kemp             return ReferenceHandler<cl_type>::retain(object_);
2357*6fee86a4SJeremy Kemp         }
2358*6fee86a4SJeremy Kemp         else {
2359*6fee86a4SJeremy Kemp             return CL_SUCCESS;
2360*6fee86a4SJeremy Kemp         }
2361*6fee86a4SJeremy Kemp     }
2362*6fee86a4SJeremy Kemp 
release() const2363*6fee86a4SJeremy Kemp     cl_int release() const
2364*6fee86a4SJeremy Kemp     {
2365*6fee86a4SJeremy Kemp         if (object_ != nullptr && referenceCountable_) {
2366*6fee86a4SJeremy Kemp             return ReferenceHandler<cl_type>::release(object_);
2367*6fee86a4SJeremy Kemp         }
2368*6fee86a4SJeremy Kemp         else {
2369*6fee86a4SJeremy Kemp             return CL_SUCCESS;
2370*6fee86a4SJeremy Kemp         }
2371*6fee86a4SJeremy Kemp     }
2372*6fee86a4SJeremy Kemp };
2373*6fee86a4SJeremy Kemp 
2374*6fee86a4SJeremy Kemp template <typename T>
operator ==(const Wrapper<T> & lhs,const Wrapper<T> & rhs)2375*6fee86a4SJeremy Kemp inline bool operator==(const Wrapper<T> &lhs, const Wrapper<T> &rhs)
2376*6fee86a4SJeremy Kemp {
2377*6fee86a4SJeremy Kemp     return lhs() == rhs();
2378*6fee86a4SJeremy Kemp }
2379*6fee86a4SJeremy Kemp 
2380*6fee86a4SJeremy Kemp template <typename T>
operator !=(const Wrapper<T> & lhs,const Wrapper<T> & rhs)2381*6fee86a4SJeremy Kemp inline bool operator!=(const Wrapper<T> &lhs, const Wrapper<T> &rhs)
2382*6fee86a4SJeremy Kemp {
2383*6fee86a4SJeremy Kemp     return !operator==(lhs, rhs);
2384*6fee86a4SJeremy Kemp }
2385*6fee86a4SJeremy Kemp 
2386*6fee86a4SJeremy Kemp } // namespace detail
2387*6fee86a4SJeremy Kemp //! \endcond
2388*6fee86a4SJeremy Kemp 
2389*6fee86a4SJeremy Kemp 
2390*6fee86a4SJeremy Kemp 
2391*6fee86a4SJeremy Kemp 
2392*6fee86a4SJeremy Kemp 
2393*6fee86a4SJeremy Kemp /*! \stuct ImageFormat
2394*6fee86a4SJeremy Kemp  *  \brief Adds constructors and member functions for cl_image_format.
2395*6fee86a4SJeremy Kemp  *
2396*6fee86a4SJeremy Kemp  *  \see cl_image_format
2397*6fee86a4SJeremy Kemp  */
2398*6fee86a4SJeremy Kemp struct ImageFormat : public cl_image_format
2399*6fee86a4SJeremy Kemp {
2400*6fee86a4SJeremy Kemp     //! \brief Default constructor - performs no initialization.
ImageFormatcl::ImageFormat2401*6fee86a4SJeremy Kemp     ImageFormat(){}
2402*6fee86a4SJeremy Kemp 
2403*6fee86a4SJeremy Kemp     //! \brief Initializing constructor.
ImageFormatcl::ImageFormat2404*6fee86a4SJeremy Kemp     ImageFormat(cl_channel_order order, cl_channel_type type)
2405*6fee86a4SJeremy Kemp     {
2406*6fee86a4SJeremy Kemp         image_channel_order = order;
2407*6fee86a4SJeremy Kemp         image_channel_data_type = type;
2408*6fee86a4SJeremy Kemp     }
2409*6fee86a4SJeremy Kemp 
2410*6fee86a4SJeremy Kemp     //! \brief Copy constructor.
ImageFormatcl::ImageFormat2411*6fee86a4SJeremy Kemp     ImageFormat(const ImageFormat &other) { *this = other; }
2412*6fee86a4SJeremy Kemp 
2413*6fee86a4SJeremy Kemp     //! \brief Assignment operator.
operator =cl::ImageFormat2414*6fee86a4SJeremy Kemp     ImageFormat& operator = (const ImageFormat& rhs)
2415*6fee86a4SJeremy Kemp     {
2416*6fee86a4SJeremy Kemp         if (this != &rhs) {
2417*6fee86a4SJeremy Kemp             this->image_channel_data_type = rhs.image_channel_data_type;
2418*6fee86a4SJeremy Kemp             this->image_channel_order     = rhs.image_channel_order;
2419*6fee86a4SJeremy Kemp         }
2420*6fee86a4SJeremy Kemp         return *this;
2421*6fee86a4SJeremy Kemp     }
2422*6fee86a4SJeremy Kemp };
2423*6fee86a4SJeremy Kemp 
2424*6fee86a4SJeremy Kemp /*! \brief Class interface for cl_device_id.
2425*6fee86a4SJeremy Kemp  *
2426*6fee86a4SJeremy Kemp  *  \note Copies of these objects are inexpensive, since they don't 'own'
2427*6fee86a4SJeremy Kemp  *        any underlying resources or data structures.
2428*6fee86a4SJeremy Kemp  *
2429*6fee86a4SJeremy Kemp  *  \see cl_device_id
2430*6fee86a4SJeremy Kemp  */
2431*6fee86a4SJeremy Kemp class Device : public detail::Wrapper<cl_device_id>
2432*6fee86a4SJeremy Kemp {
2433*6fee86a4SJeremy Kemp private:
2434*6fee86a4SJeremy Kemp     static std::once_flag default_initialized_;
2435*6fee86a4SJeremy Kemp     static Device default_;
2436*6fee86a4SJeremy Kemp     static cl_int default_error_;
2437*6fee86a4SJeremy Kemp 
2438*6fee86a4SJeremy Kemp     /*! \brief Create the default context.
2439*6fee86a4SJeremy Kemp     *
2440*6fee86a4SJeremy Kemp     * This sets @c default_ and @c default_error_. It does not throw
2441*6fee86a4SJeremy Kemp     * @c cl::Error.
2442*6fee86a4SJeremy Kemp     */
2443*6fee86a4SJeremy Kemp     static void makeDefault();
2444*6fee86a4SJeremy Kemp 
2445*6fee86a4SJeremy Kemp     /*! \brief Create the default platform from a provided platform.
2446*6fee86a4SJeremy Kemp     *
2447*6fee86a4SJeremy Kemp     * This sets @c default_. It does not throw
2448*6fee86a4SJeremy Kemp     * @c cl::Error.
2449*6fee86a4SJeremy Kemp     */
makeDefaultProvided(const Device & p)2450*6fee86a4SJeremy Kemp     static void makeDefaultProvided(const Device &p) {
2451*6fee86a4SJeremy Kemp         default_ = p;
2452*6fee86a4SJeremy Kemp     }
2453*6fee86a4SJeremy Kemp 
2454*6fee86a4SJeremy Kemp public:
2455*6fee86a4SJeremy Kemp #ifdef CL_HPP_UNIT_TEST_ENABLE
2456*6fee86a4SJeremy Kemp     /*! \brief Reset the default.
2457*6fee86a4SJeremy Kemp     *
2458*6fee86a4SJeremy Kemp     * This sets @c default_ to an empty value to support cleanup in
2459*6fee86a4SJeremy Kemp     * the unit test framework.
2460*6fee86a4SJeremy Kemp     * This function is not thread safe.
2461*6fee86a4SJeremy Kemp     */
unitTestClearDefault()2462*6fee86a4SJeremy Kemp     static void unitTestClearDefault() {
2463*6fee86a4SJeremy Kemp         default_ = Device();
2464*6fee86a4SJeremy Kemp     }
2465*6fee86a4SJeremy Kemp #endif // #ifdef CL_HPP_UNIT_TEST_ENABLE
2466*6fee86a4SJeremy Kemp 
2467*6fee86a4SJeremy Kemp     //! \brief Default constructor - initializes to nullptr.
Device()2468*6fee86a4SJeremy Kemp     Device() : detail::Wrapper<cl_type>() { }
2469*6fee86a4SJeremy Kemp 
2470*6fee86a4SJeremy Kemp     /*! \brief Constructor from cl_device_id.
2471*6fee86a4SJeremy Kemp      *
2472*6fee86a4SJeremy Kemp      *  This simply copies the device ID value, which is an inexpensive operation.
2473*6fee86a4SJeremy Kemp      */
Device(const cl_device_id & device,bool retainObject=false)2474*6fee86a4SJeremy Kemp     explicit Device(const cl_device_id &device, bool retainObject = false) :
2475*6fee86a4SJeremy Kemp         detail::Wrapper<cl_type>(device, retainObject) { }
2476*6fee86a4SJeremy Kemp 
2477*6fee86a4SJeremy Kemp     /*! \brief Returns the first device on the default context.
2478*6fee86a4SJeremy Kemp      *
2479*6fee86a4SJeremy Kemp      *  \see Context::getDefault()
2480*6fee86a4SJeremy Kemp      */
getDefault(cl_int * errResult=nullptr)2481*6fee86a4SJeremy Kemp     static Device getDefault(
2482*6fee86a4SJeremy Kemp         cl_int *errResult = nullptr)
2483*6fee86a4SJeremy Kemp     {
2484*6fee86a4SJeremy Kemp         std::call_once(default_initialized_, makeDefault);
2485*6fee86a4SJeremy Kemp         detail::errHandler(default_error_);
2486*6fee86a4SJeremy Kemp         if (errResult != nullptr) {
2487*6fee86a4SJeremy Kemp             *errResult = default_error_;
2488*6fee86a4SJeremy Kemp         }
2489*6fee86a4SJeremy Kemp         return default_;
2490*6fee86a4SJeremy Kemp     }
2491*6fee86a4SJeremy Kemp 
2492*6fee86a4SJeremy Kemp     /**
2493*6fee86a4SJeremy Kemp     * Modify the default device to be used by
2494*6fee86a4SJeremy Kemp     * subsequent operations.
2495*6fee86a4SJeremy Kemp     * Will only set the default if no default was previously created.
2496*6fee86a4SJeremy Kemp     * @return updated default device.
2497*6fee86a4SJeremy Kemp     *         Should be compared to the passed value to ensure that it was updated.
2498*6fee86a4SJeremy Kemp     */
setDefault(const Device & default_device)2499*6fee86a4SJeremy Kemp     static Device setDefault(const Device &default_device)
2500*6fee86a4SJeremy Kemp     {
2501*6fee86a4SJeremy Kemp         std::call_once(default_initialized_, makeDefaultProvided, std::cref(default_device));
2502*6fee86a4SJeremy Kemp         detail::errHandler(default_error_);
2503*6fee86a4SJeremy Kemp         return default_;
2504*6fee86a4SJeremy Kemp     }
2505*6fee86a4SJeremy Kemp 
2506*6fee86a4SJeremy Kemp     /*! \brief Assignment operator from cl_device_id.
2507*6fee86a4SJeremy Kemp      *
2508*6fee86a4SJeremy Kemp      *  This simply copies the device ID value, which is an inexpensive operation.
2509*6fee86a4SJeremy Kemp      */
operator =(const cl_device_id & rhs)2510*6fee86a4SJeremy Kemp     Device& operator = (const cl_device_id& rhs)
2511*6fee86a4SJeremy Kemp     {
2512*6fee86a4SJeremy Kemp         detail::Wrapper<cl_type>::operator=(rhs);
2513*6fee86a4SJeremy Kemp         return *this;
2514*6fee86a4SJeremy Kemp     }
2515*6fee86a4SJeremy Kemp 
2516*6fee86a4SJeremy Kemp 
2517*6fee86a4SJeremy Kemp     //! \brief Wrapper for clGetDeviceInfo().
2518*6fee86a4SJeremy Kemp     template <typename T>
getInfo(cl_device_info name,T * param) const2519*6fee86a4SJeremy Kemp     cl_int getInfo(cl_device_info name, T* param) const
2520*6fee86a4SJeremy Kemp     {
2521*6fee86a4SJeremy Kemp         return detail::errHandler(
2522*6fee86a4SJeremy Kemp             detail::getInfo(&::clGetDeviceInfo, object_, name, param),
2523*6fee86a4SJeremy Kemp             __GET_DEVICE_INFO_ERR);
2524*6fee86a4SJeremy Kemp     }
2525*6fee86a4SJeremy Kemp 
2526*6fee86a4SJeremy Kemp     //! \brief Wrapper for clGetDeviceInfo() that returns by value.
2527*6fee86a4SJeremy Kemp     template <cl_device_info name> typename
2528*6fee86a4SJeremy Kemp     detail::param_traits<detail::cl_device_info, name>::param_type
getInfo(cl_int * err=nullptr) const2529*6fee86a4SJeremy Kemp     getInfo(cl_int* err = nullptr) const
2530*6fee86a4SJeremy Kemp     {
2531*6fee86a4SJeremy Kemp         typename detail::param_traits<
2532*6fee86a4SJeremy Kemp             detail::cl_device_info, name>::param_type param;
2533*6fee86a4SJeremy Kemp         cl_int result = getInfo(name, &param);
2534*6fee86a4SJeremy Kemp         if (err != nullptr) {
2535*6fee86a4SJeremy Kemp             *err = result;
2536*6fee86a4SJeremy Kemp         }
2537*6fee86a4SJeremy Kemp         return param;
2538*6fee86a4SJeremy Kemp     }
2539*6fee86a4SJeremy Kemp 
2540*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 210
2541*6fee86a4SJeremy Kemp     /**
2542*6fee86a4SJeremy Kemp      * Return the current value of the host clock as seen by the device.
2543*6fee86a4SJeremy Kemp      * The resolution of the device timer may be queried with the
2544*6fee86a4SJeremy Kemp      * CL_DEVICE_PROFILING_TIMER_RESOLUTION query.
2545*6fee86a4SJeremy Kemp      * @return The host timer value.
2546*6fee86a4SJeremy Kemp      */
getHostTimer(cl_int * error=nullptr)2547*6fee86a4SJeremy Kemp     cl_ulong getHostTimer(cl_int *error = nullptr)
2548*6fee86a4SJeremy Kemp     {
2549*6fee86a4SJeremy Kemp         cl_ulong retVal = 0;
2550*6fee86a4SJeremy Kemp         cl_int err =
2551*6fee86a4SJeremy Kemp             clGetHostTimer(this->get(), &retVal);
2552*6fee86a4SJeremy Kemp         detail::errHandler(
2553*6fee86a4SJeremy Kemp             err,
2554*6fee86a4SJeremy Kemp             __GET_HOST_TIMER_ERR);
2555*6fee86a4SJeremy Kemp         if (error) {
2556*6fee86a4SJeremy Kemp             *error = err;
2557*6fee86a4SJeremy Kemp         }
2558*6fee86a4SJeremy Kemp         return retVal;
2559*6fee86a4SJeremy Kemp     }
2560*6fee86a4SJeremy Kemp 
2561*6fee86a4SJeremy Kemp     /**
2562*6fee86a4SJeremy Kemp      * Return a synchronized pair of host and device timestamps as seen by device.
2563*6fee86a4SJeremy Kemp      * Use to correlate the clocks and get the host timer only using getHostTimer
2564*6fee86a4SJeremy Kemp      * as a lower cost mechanism in between calls.
2565*6fee86a4SJeremy Kemp      * The resolution of the host timer may be queried with the
2566*6fee86a4SJeremy Kemp      * CL_PLATFORM_HOST_TIMER_RESOLUTION query.
2567*6fee86a4SJeremy Kemp      * The resolution of the device timer may be queried with the
2568*6fee86a4SJeremy Kemp      * CL_DEVICE_PROFILING_TIMER_RESOLUTION query.
2569*6fee86a4SJeremy Kemp      * @return A pair of (device timer, host timer) timer values.
2570*6fee86a4SJeremy Kemp      */
getDeviceAndHostTimer(cl_int * error=nullptr)2571*6fee86a4SJeremy Kemp     std::pair<cl_ulong, cl_ulong> getDeviceAndHostTimer(cl_int *error = nullptr)
2572*6fee86a4SJeremy Kemp     {
2573*6fee86a4SJeremy Kemp         std::pair<cl_ulong, cl_ulong> retVal;
2574*6fee86a4SJeremy Kemp         cl_int err =
2575*6fee86a4SJeremy Kemp             clGetDeviceAndHostTimer(this->get(), &(retVal.first), &(retVal.second));
2576*6fee86a4SJeremy Kemp         detail::errHandler(
2577*6fee86a4SJeremy Kemp             err,
2578*6fee86a4SJeremy Kemp             __GET_DEVICE_AND_HOST_TIMER_ERR);
2579*6fee86a4SJeremy Kemp         if (error) {
2580*6fee86a4SJeremy Kemp             *error = err;
2581*6fee86a4SJeremy Kemp         }
2582*6fee86a4SJeremy Kemp         return retVal;
2583*6fee86a4SJeremy Kemp     }
2584*6fee86a4SJeremy Kemp #endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 210
2585*6fee86a4SJeremy Kemp 
2586*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 120
2587*6fee86a4SJeremy Kemp     //! \brief Wrapper for clCreateSubDevices().
2588*6fee86a4SJeremy Kemp     cl_int createSubDevices(const cl_device_partition_property* properties,
2589*6fee86a4SJeremy Kemp                             vector<Device>* devices);
2590*6fee86a4SJeremy Kemp #endif // defined (CL_HPP_TARGET_OPENCL_VERSION >= 120)
2591*6fee86a4SJeremy Kemp 
2592*6fee86a4SJeremy Kemp #if defined(cl_ext_device_fission)
2593*6fee86a4SJeremy Kemp     //! \brief Wrapper for clCreateSubDevices().
2594*6fee86a4SJeremy Kemp     cl_int createSubDevices(const cl_device_partition_property_ext* properties,
2595*6fee86a4SJeremy Kemp                             vector<Device>* devices);
2596*6fee86a4SJeremy Kemp #endif // defined(cl_ext_device_fission)
2597*6fee86a4SJeremy Kemp };
2598*6fee86a4SJeremy Kemp 
2599*6fee86a4SJeremy Kemp using BuildLogType = vector<std::pair<cl::Device, typename detail::param_traits<detail::cl_program_build_info, CL_PROGRAM_BUILD_LOG>::param_type>>;
2600*6fee86a4SJeremy Kemp #if defined(CL_HPP_ENABLE_EXCEPTIONS)
2601*6fee86a4SJeremy Kemp /**
2602*6fee86a4SJeremy Kemp * Exception class for build errors to carry build info
2603*6fee86a4SJeremy Kemp */
2604*6fee86a4SJeremy Kemp class BuildError : public Error
2605*6fee86a4SJeremy Kemp {
2606*6fee86a4SJeremy Kemp private:
2607*6fee86a4SJeremy Kemp     BuildLogType buildLogs;
2608*6fee86a4SJeremy Kemp public:
BuildError(cl_int err,const char * errStr,const BuildLogType & vec)2609*6fee86a4SJeremy Kemp     BuildError(cl_int err, const char * errStr, const BuildLogType &vec) : Error(err, errStr), buildLogs(vec)
2610*6fee86a4SJeremy Kemp     {
2611*6fee86a4SJeremy Kemp     }
2612*6fee86a4SJeremy Kemp 
getBuildLog() const2613*6fee86a4SJeremy Kemp     BuildLogType getBuildLog() const
2614*6fee86a4SJeremy Kemp     {
2615*6fee86a4SJeremy Kemp         return buildLogs;
2616*6fee86a4SJeremy Kemp     }
2617*6fee86a4SJeremy Kemp };
2618*6fee86a4SJeremy Kemp namespace detail {
buildErrHandler(cl_int err,const char * errStr,const BuildLogType & buildLogs)2619*6fee86a4SJeremy Kemp     static inline cl_int buildErrHandler(
2620*6fee86a4SJeremy Kemp         cl_int err,
2621*6fee86a4SJeremy Kemp         const char * errStr,
2622*6fee86a4SJeremy Kemp         const BuildLogType &buildLogs)
2623*6fee86a4SJeremy Kemp     {
2624*6fee86a4SJeremy Kemp         if (err != CL_SUCCESS) {
2625*6fee86a4SJeremy Kemp             throw BuildError(err, errStr, buildLogs);
2626*6fee86a4SJeremy Kemp         }
2627*6fee86a4SJeremy Kemp         return err;
2628*6fee86a4SJeremy Kemp     }
2629*6fee86a4SJeremy Kemp } // namespace detail
2630*6fee86a4SJeremy Kemp 
2631*6fee86a4SJeremy Kemp #else
2632*6fee86a4SJeremy Kemp namespace detail {
buildErrHandler(cl_int err,const char * errStr,const BuildLogType & buildLogs)2633*6fee86a4SJeremy Kemp     static inline cl_int buildErrHandler(
2634*6fee86a4SJeremy Kemp         cl_int err,
2635*6fee86a4SJeremy Kemp         const char * errStr,
2636*6fee86a4SJeremy Kemp         const BuildLogType &buildLogs)
2637*6fee86a4SJeremy Kemp     {
2638*6fee86a4SJeremy Kemp         (void)buildLogs; // suppress unused variable warning
2639*6fee86a4SJeremy Kemp         (void)errStr;
2640*6fee86a4SJeremy Kemp         return err;
2641*6fee86a4SJeremy Kemp     }
2642*6fee86a4SJeremy Kemp } // namespace detail
2643*6fee86a4SJeremy Kemp #endif // #if defined(CL_HPP_ENABLE_EXCEPTIONS)
2644*6fee86a4SJeremy Kemp 
2645*6fee86a4SJeremy Kemp CL_HPP_DEFINE_STATIC_MEMBER_ std::once_flag Device::default_initialized_;
2646*6fee86a4SJeremy Kemp CL_HPP_DEFINE_STATIC_MEMBER_ Device Device::default_;
2647*6fee86a4SJeremy Kemp CL_HPP_DEFINE_STATIC_MEMBER_ cl_int Device::default_error_ = CL_SUCCESS;
2648*6fee86a4SJeremy Kemp 
2649*6fee86a4SJeremy Kemp /*! \brief Class interface for cl_platform_id.
2650*6fee86a4SJeremy Kemp  *
2651*6fee86a4SJeremy Kemp  *  \note Copies of these objects are inexpensive, since they don't 'own'
2652*6fee86a4SJeremy Kemp  *        any underlying resources or data structures.
2653*6fee86a4SJeremy Kemp  *
2654*6fee86a4SJeremy Kemp  *  \see cl_platform_id
2655*6fee86a4SJeremy Kemp  */
2656*6fee86a4SJeremy Kemp class Platform : public detail::Wrapper<cl_platform_id>
2657*6fee86a4SJeremy Kemp {
2658*6fee86a4SJeremy Kemp private:
2659*6fee86a4SJeremy Kemp     static std::once_flag default_initialized_;
2660*6fee86a4SJeremy Kemp     static Platform default_;
2661*6fee86a4SJeremy Kemp     static cl_int default_error_;
2662*6fee86a4SJeremy Kemp 
2663*6fee86a4SJeremy Kemp     /*! \brief Create the default context.
2664*6fee86a4SJeremy Kemp     *
2665*6fee86a4SJeremy Kemp     * This sets @c default_ and @c default_error_. It does not throw
2666*6fee86a4SJeremy Kemp     * @c cl::Error.
2667*6fee86a4SJeremy Kemp     */
makeDefault()2668*6fee86a4SJeremy Kemp     static void makeDefault() {
2669*6fee86a4SJeremy Kemp         /* Throwing an exception from a call_once invocation does not do
2670*6fee86a4SJeremy Kemp         * what we wish, so we catch it and save the error.
2671*6fee86a4SJeremy Kemp         */
2672*6fee86a4SJeremy Kemp #if defined(CL_HPP_ENABLE_EXCEPTIONS)
2673*6fee86a4SJeremy Kemp         try
2674*6fee86a4SJeremy Kemp #endif
2675*6fee86a4SJeremy Kemp         {
2676*6fee86a4SJeremy Kemp             // If default wasn't passed ,generate one
2677*6fee86a4SJeremy Kemp             // Otherwise set it
2678*6fee86a4SJeremy Kemp             cl_uint n = 0;
2679*6fee86a4SJeremy Kemp 
2680*6fee86a4SJeremy Kemp             cl_int err = ::clGetPlatformIDs(0, nullptr, &n);
2681*6fee86a4SJeremy Kemp             if (err != CL_SUCCESS) {
2682*6fee86a4SJeremy Kemp                 default_error_ = err;
2683*6fee86a4SJeremy Kemp                 return;
2684*6fee86a4SJeremy Kemp             }
2685*6fee86a4SJeremy Kemp             if (n == 0) {
2686*6fee86a4SJeremy Kemp                 default_error_ = CL_INVALID_PLATFORM;
2687*6fee86a4SJeremy Kemp                 return;
2688*6fee86a4SJeremy Kemp             }
2689*6fee86a4SJeremy Kemp 
2690*6fee86a4SJeremy Kemp             vector<cl_platform_id> ids(n);
2691*6fee86a4SJeremy Kemp             err = ::clGetPlatformIDs(n, ids.data(), nullptr);
2692*6fee86a4SJeremy Kemp             if (err != CL_SUCCESS) {
2693*6fee86a4SJeremy Kemp                 default_error_ = err;
2694*6fee86a4SJeremy Kemp                 return;
2695*6fee86a4SJeremy Kemp             }
2696*6fee86a4SJeremy Kemp 
2697*6fee86a4SJeremy Kemp             default_ = Platform(ids[0]);
2698*6fee86a4SJeremy Kemp         }
2699*6fee86a4SJeremy Kemp #if defined(CL_HPP_ENABLE_EXCEPTIONS)
2700*6fee86a4SJeremy Kemp         catch (cl::Error &e) {
2701*6fee86a4SJeremy Kemp             default_error_ = e.err();
2702*6fee86a4SJeremy Kemp         }
2703*6fee86a4SJeremy Kemp #endif
2704*6fee86a4SJeremy Kemp     }
2705*6fee86a4SJeremy Kemp 
2706*6fee86a4SJeremy Kemp     /*! \brief Create the default platform from a provided platform.
2707*6fee86a4SJeremy Kemp      *
2708*6fee86a4SJeremy Kemp      * This sets @c default_. It does not throw
2709*6fee86a4SJeremy Kemp      * @c cl::Error.
2710*6fee86a4SJeremy Kemp      */
makeDefaultProvided(const Platform & p)2711*6fee86a4SJeremy Kemp     static void makeDefaultProvided(const Platform &p) {
2712*6fee86a4SJeremy Kemp        default_ = p;
2713*6fee86a4SJeremy Kemp     }
2714*6fee86a4SJeremy Kemp 
2715*6fee86a4SJeremy Kemp public:
2716*6fee86a4SJeremy Kemp #ifdef CL_HPP_UNIT_TEST_ENABLE
2717*6fee86a4SJeremy Kemp     /*! \brief Reset the default.
2718*6fee86a4SJeremy Kemp     *
2719*6fee86a4SJeremy Kemp     * This sets @c default_ to an empty value to support cleanup in
2720*6fee86a4SJeremy Kemp     * the unit test framework.
2721*6fee86a4SJeremy Kemp     * This function is not thread safe.
2722*6fee86a4SJeremy Kemp     */
unitTestClearDefault()2723*6fee86a4SJeremy Kemp     static void unitTestClearDefault() {
2724*6fee86a4SJeremy Kemp         default_ = Platform();
2725*6fee86a4SJeremy Kemp     }
2726*6fee86a4SJeremy Kemp #endif // #ifdef CL_HPP_UNIT_TEST_ENABLE
2727*6fee86a4SJeremy Kemp 
2728*6fee86a4SJeremy Kemp     //! \brief Default constructor - initializes to nullptr.
Platform()2729*6fee86a4SJeremy Kemp     Platform() : detail::Wrapper<cl_type>()  { }
2730*6fee86a4SJeremy Kemp 
2731*6fee86a4SJeremy Kemp     /*! \brief Constructor from cl_platform_id.
2732*6fee86a4SJeremy Kemp      *
2733*6fee86a4SJeremy Kemp      * \param retainObject will cause the constructor to retain its cl object.
2734*6fee86a4SJeremy Kemp      *                     Defaults to false to maintain compatibility with
2735*6fee86a4SJeremy Kemp      *                     earlier versions.
2736*6fee86a4SJeremy Kemp      *  This simply copies the platform ID value, which is an inexpensive operation.
2737*6fee86a4SJeremy Kemp      */
Platform(const cl_platform_id & platform,bool retainObject=false)2738*6fee86a4SJeremy Kemp     explicit Platform(const cl_platform_id &platform, bool retainObject = false) :
2739*6fee86a4SJeremy Kemp         detail::Wrapper<cl_type>(platform, retainObject) { }
2740*6fee86a4SJeremy Kemp 
2741*6fee86a4SJeremy Kemp     /*! \brief Assignment operator from cl_platform_id.
2742*6fee86a4SJeremy Kemp      *
2743*6fee86a4SJeremy Kemp      *  This simply copies the platform ID value, which is an inexpensive operation.
2744*6fee86a4SJeremy Kemp      */
operator =(const cl_platform_id & rhs)2745*6fee86a4SJeremy Kemp     Platform& operator = (const cl_platform_id& rhs)
2746*6fee86a4SJeremy Kemp     {
2747*6fee86a4SJeremy Kemp         detail::Wrapper<cl_type>::operator=(rhs);
2748*6fee86a4SJeremy Kemp         return *this;
2749*6fee86a4SJeremy Kemp     }
2750*6fee86a4SJeremy Kemp 
getDefault(cl_int * errResult=nullptr)2751*6fee86a4SJeremy Kemp     static Platform getDefault(
2752*6fee86a4SJeremy Kemp         cl_int *errResult = nullptr)
2753*6fee86a4SJeremy Kemp     {
2754*6fee86a4SJeremy Kemp         std::call_once(default_initialized_, makeDefault);
2755*6fee86a4SJeremy Kemp         detail::errHandler(default_error_);
2756*6fee86a4SJeremy Kemp         if (errResult != nullptr) {
2757*6fee86a4SJeremy Kemp             *errResult = default_error_;
2758*6fee86a4SJeremy Kemp         }
2759*6fee86a4SJeremy Kemp         return default_;
2760*6fee86a4SJeremy Kemp     }
2761*6fee86a4SJeremy Kemp 
2762*6fee86a4SJeremy Kemp     /**
2763*6fee86a4SJeremy Kemp      * Modify the default platform to be used by
2764*6fee86a4SJeremy Kemp      * subsequent operations.
2765*6fee86a4SJeremy Kemp      * Will only set the default if no default was previously created.
2766*6fee86a4SJeremy Kemp      * @return updated default platform.
2767*6fee86a4SJeremy Kemp      *         Should be compared to the passed value to ensure that it was updated.
2768*6fee86a4SJeremy Kemp      */
setDefault(const Platform & default_platform)2769*6fee86a4SJeremy Kemp     static Platform setDefault(const Platform &default_platform)
2770*6fee86a4SJeremy Kemp     {
2771*6fee86a4SJeremy Kemp         std::call_once(default_initialized_, makeDefaultProvided, std::cref(default_platform));
2772*6fee86a4SJeremy Kemp         detail::errHandler(default_error_);
2773*6fee86a4SJeremy Kemp         return default_;
2774*6fee86a4SJeremy Kemp     }
2775*6fee86a4SJeremy Kemp 
2776*6fee86a4SJeremy Kemp     //! \brief Wrapper for clGetPlatformInfo().
2777*6fee86a4SJeremy Kemp     template <typename T>
getInfo(cl_platform_info name,T * param) const2778*6fee86a4SJeremy Kemp     cl_int getInfo(cl_platform_info name, T* param) const
2779*6fee86a4SJeremy Kemp     {
2780*6fee86a4SJeremy Kemp         return detail::errHandler(
2781*6fee86a4SJeremy Kemp             detail::getInfo(&::clGetPlatformInfo, object_, name, param),
2782*6fee86a4SJeremy Kemp             __GET_PLATFORM_INFO_ERR);
2783*6fee86a4SJeremy Kemp     }
2784*6fee86a4SJeremy Kemp 
2785*6fee86a4SJeremy Kemp     //! \brief Wrapper for clGetPlatformInfo() that returns by value.
2786*6fee86a4SJeremy Kemp     template <cl_platform_info name> typename
2787*6fee86a4SJeremy Kemp     detail::param_traits<detail::cl_platform_info, name>::param_type
getInfo(cl_int * err=nullptr) const2788*6fee86a4SJeremy Kemp     getInfo(cl_int* err = nullptr) const
2789*6fee86a4SJeremy Kemp     {
2790*6fee86a4SJeremy Kemp         typename detail::param_traits<
2791*6fee86a4SJeremy Kemp             detail::cl_platform_info, name>::param_type param;
2792*6fee86a4SJeremy Kemp         cl_int result = getInfo(name, &param);
2793*6fee86a4SJeremy Kemp         if (err != nullptr) {
2794*6fee86a4SJeremy Kemp             *err = result;
2795*6fee86a4SJeremy Kemp         }
2796*6fee86a4SJeremy Kemp         return param;
2797*6fee86a4SJeremy Kemp     }
2798*6fee86a4SJeremy Kemp 
2799*6fee86a4SJeremy Kemp     /*! \brief Gets a list of devices for this platform.
2800*6fee86a4SJeremy Kemp      *
2801*6fee86a4SJeremy Kemp      *  Wraps clGetDeviceIDs().
2802*6fee86a4SJeremy Kemp      */
getDevices(cl_device_type type,vector<Device> * devices) const2803*6fee86a4SJeremy Kemp     cl_int getDevices(
2804*6fee86a4SJeremy Kemp         cl_device_type type,
2805*6fee86a4SJeremy Kemp         vector<Device>* devices) const
2806*6fee86a4SJeremy Kemp     {
2807*6fee86a4SJeremy Kemp         cl_uint n = 0;
2808*6fee86a4SJeremy Kemp         if( devices == nullptr ) {
2809*6fee86a4SJeremy Kemp             return detail::errHandler(CL_INVALID_ARG_VALUE, __GET_DEVICE_IDS_ERR);
2810*6fee86a4SJeremy Kemp         }
2811*6fee86a4SJeremy Kemp         cl_int err = ::clGetDeviceIDs(object_, type, 0, nullptr, &n);
2812*6fee86a4SJeremy Kemp         if (err != CL_SUCCESS  && err != CL_DEVICE_NOT_FOUND) {
2813*6fee86a4SJeremy Kemp             return detail::errHandler(err, __GET_DEVICE_IDS_ERR);
2814*6fee86a4SJeremy Kemp         }
2815*6fee86a4SJeremy Kemp 
2816*6fee86a4SJeremy Kemp         vector<cl_device_id> ids(n);
2817*6fee86a4SJeremy Kemp         if (n>0) {
2818*6fee86a4SJeremy Kemp             err = ::clGetDeviceIDs(object_, type, n, ids.data(), nullptr);
2819*6fee86a4SJeremy Kemp             if (err != CL_SUCCESS) {
2820*6fee86a4SJeremy Kemp                 return detail::errHandler(err, __GET_DEVICE_IDS_ERR);
2821*6fee86a4SJeremy Kemp             }
2822*6fee86a4SJeremy Kemp         }
2823*6fee86a4SJeremy Kemp 
2824*6fee86a4SJeremy Kemp         // Cannot trivially assign because we need to capture intermediates
2825*6fee86a4SJeremy Kemp         // with safe construction
2826*6fee86a4SJeremy Kemp         // We must retain things we obtain from the API to avoid releasing
2827*6fee86a4SJeremy Kemp         // API-owned objects.
2828*6fee86a4SJeremy Kemp         if (devices) {
2829*6fee86a4SJeremy Kemp             devices->resize(ids.size());
2830*6fee86a4SJeremy Kemp 
2831*6fee86a4SJeremy Kemp             // Assign to param, constructing with retain behaviour
2832*6fee86a4SJeremy Kemp             // to correctly capture each underlying CL object
2833*6fee86a4SJeremy Kemp             for (size_type i = 0; i < ids.size(); i++) {
2834*6fee86a4SJeremy Kemp                 (*devices)[i] = Device(ids[i], true);
2835*6fee86a4SJeremy Kemp             }
2836*6fee86a4SJeremy Kemp         }
2837*6fee86a4SJeremy Kemp         return CL_SUCCESS;
2838*6fee86a4SJeremy Kemp     }
2839*6fee86a4SJeremy Kemp 
2840*6fee86a4SJeremy Kemp #if defined(CL_HPP_USE_DX_INTEROP)
2841*6fee86a4SJeremy Kemp    /*! \brief Get the list of available D3D10 devices.
2842*6fee86a4SJeremy Kemp      *
2843*6fee86a4SJeremy Kemp      *  \param d3d_device_source.
2844*6fee86a4SJeremy Kemp      *
2845*6fee86a4SJeremy Kemp      *  \param d3d_object.
2846*6fee86a4SJeremy Kemp      *
2847*6fee86a4SJeremy Kemp      *  \param d3d_device_set.
2848*6fee86a4SJeremy Kemp      *
2849*6fee86a4SJeremy Kemp      *  \param devices returns a vector of OpenCL D3D10 devices found. The cl::Device
2850*6fee86a4SJeremy Kemp      *  values returned in devices can be used to identify a specific OpenCL
2851*6fee86a4SJeremy Kemp      *  device. If \a devices argument is nullptr, this argument is ignored.
2852*6fee86a4SJeremy Kemp      *
2853*6fee86a4SJeremy Kemp      *  \return One of the following values:
2854*6fee86a4SJeremy Kemp      *    - CL_SUCCESS if the function is executed successfully.
2855*6fee86a4SJeremy Kemp      *
2856*6fee86a4SJeremy Kemp      *  The application can query specific capabilities of the OpenCL device(s)
2857*6fee86a4SJeremy Kemp      *  returned by cl::getDevices. This can be used by the application to
2858*6fee86a4SJeremy Kemp      *  determine which device(s) to use.
2859*6fee86a4SJeremy Kemp      *
2860*6fee86a4SJeremy Kemp      * \note In the case that exceptions are enabled and a return value
2861*6fee86a4SJeremy Kemp      * other than CL_SUCCESS is generated, then cl::Error exception is
2862*6fee86a4SJeremy Kemp      * generated.
2863*6fee86a4SJeremy Kemp      */
getDevices(cl_d3d10_device_source_khr d3d_device_source,void * d3d_object,cl_d3d10_device_set_khr d3d_device_set,vector<Device> * devices) const2864*6fee86a4SJeremy Kemp     cl_int getDevices(
2865*6fee86a4SJeremy Kemp         cl_d3d10_device_source_khr d3d_device_source,
2866*6fee86a4SJeremy Kemp         void *                     d3d_object,
2867*6fee86a4SJeremy Kemp         cl_d3d10_device_set_khr    d3d_device_set,
2868*6fee86a4SJeremy Kemp         vector<Device>* devices) const
2869*6fee86a4SJeremy Kemp     {
2870*6fee86a4SJeremy Kemp         typedef CL_API_ENTRY cl_int (CL_API_CALL *PFN_clGetDeviceIDsFromD3D10KHR)(
2871*6fee86a4SJeremy Kemp             cl_platform_id platform,
2872*6fee86a4SJeremy Kemp             cl_d3d10_device_source_khr d3d_device_source,
2873*6fee86a4SJeremy Kemp             void * d3d_object,
2874*6fee86a4SJeremy Kemp             cl_d3d10_device_set_khr d3d_device_set,
2875*6fee86a4SJeremy Kemp             cl_uint num_entries,
2876*6fee86a4SJeremy Kemp             cl_device_id * devices,
2877*6fee86a4SJeremy Kemp             cl_uint* num_devices);
2878*6fee86a4SJeremy Kemp 
2879*6fee86a4SJeremy Kemp         if( devices == nullptr ) {
2880*6fee86a4SJeremy Kemp             return detail::errHandler(CL_INVALID_ARG_VALUE, __GET_DEVICE_IDS_ERR);
2881*6fee86a4SJeremy Kemp         }
2882*6fee86a4SJeremy Kemp 
2883*6fee86a4SJeremy Kemp         static PFN_clGetDeviceIDsFromD3D10KHR pfn_clGetDeviceIDsFromD3D10KHR = nullptr;
2884*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 120
2885*6fee86a4SJeremy Kemp         CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(object_, clGetDeviceIDsFromD3D10KHR);
2886*6fee86a4SJeremy Kemp #endif
2887*6fee86a4SJeremy Kemp #if CL_HPP_MINIMUM_OPENCL_VERSION < 120
2888*6fee86a4SJeremy Kemp         CL_HPP_INIT_CL_EXT_FCN_PTR_(clGetDeviceIDsFromD3D10KHR);
2889*6fee86a4SJeremy Kemp #endif
2890*6fee86a4SJeremy Kemp 
2891*6fee86a4SJeremy Kemp         cl_uint n = 0;
2892*6fee86a4SJeremy Kemp         cl_int err = pfn_clGetDeviceIDsFromD3D10KHR(
2893*6fee86a4SJeremy Kemp             object_,
2894*6fee86a4SJeremy Kemp             d3d_device_source,
2895*6fee86a4SJeremy Kemp             d3d_object,
2896*6fee86a4SJeremy Kemp             d3d_device_set,
2897*6fee86a4SJeremy Kemp             0,
2898*6fee86a4SJeremy Kemp             nullptr,
2899*6fee86a4SJeremy Kemp             &n);
2900*6fee86a4SJeremy Kemp         if (err != CL_SUCCESS) {
2901*6fee86a4SJeremy Kemp             return detail::errHandler(err, __GET_DEVICE_IDS_ERR);
2902*6fee86a4SJeremy Kemp         }
2903*6fee86a4SJeremy Kemp 
2904*6fee86a4SJeremy Kemp         vector<cl_device_id> ids(n);
2905*6fee86a4SJeremy Kemp         err = pfn_clGetDeviceIDsFromD3D10KHR(
2906*6fee86a4SJeremy Kemp             object_,
2907*6fee86a4SJeremy Kemp             d3d_device_source,
2908*6fee86a4SJeremy Kemp             d3d_object,
2909*6fee86a4SJeremy Kemp             d3d_device_set,
2910*6fee86a4SJeremy Kemp             n,
2911*6fee86a4SJeremy Kemp             ids.data(),
2912*6fee86a4SJeremy Kemp             nullptr);
2913*6fee86a4SJeremy Kemp         if (err != CL_SUCCESS) {
2914*6fee86a4SJeremy Kemp             return detail::errHandler(err, __GET_DEVICE_IDS_ERR);
2915*6fee86a4SJeremy Kemp         }
2916*6fee86a4SJeremy Kemp 
2917*6fee86a4SJeremy Kemp         // Cannot trivially assign because we need to capture intermediates
2918*6fee86a4SJeremy Kemp         // with safe construction
2919*6fee86a4SJeremy Kemp         // We must retain things we obtain from the API to avoid releasing
2920*6fee86a4SJeremy Kemp         // API-owned objects.
2921*6fee86a4SJeremy Kemp         if (devices) {
2922*6fee86a4SJeremy Kemp             devices->resize(ids.size());
2923*6fee86a4SJeremy Kemp 
2924*6fee86a4SJeremy Kemp             // Assign to param, constructing with retain behaviour
2925*6fee86a4SJeremy Kemp             // to correctly capture each underlying CL object
2926*6fee86a4SJeremy Kemp             for (size_type i = 0; i < ids.size(); i++) {
2927*6fee86a4SJeremy Kemp                 (*devices)[i] = Device(ids[i], true);
2928*6fee86a4SJeremy Kemp             }
2929*6fee86a4SJeremy Kemp         }
2930*6fee86a4SJeremy Kemp         return CL_SUCCESS;
2931*6fee86a4SJeremy Kemp     }
2932*6fee86a4SJeremy Kemp #endif
2933*6fee86a4SJeremy Kemp 
2934*6fee86a4SJeremy Kemp     /*! \brief Gets a list of available platforms.
2935*6fee86a4SJeremy Kemp      *
2936*6fee86a4SJeremy Kemp      *  Wraps clGetPlatformIDs().
2937*6fee86a4SJeremy Kemp      */
get(vector<Platform> * platforms)2938*6fee86a4SJeremy Kemp     static cl_int get(
2939*6fee86a4SJeremy Kemp         vector<Platform>* platforms)
2940*6fee86a4SJeremy Kemp     {
2941*6fee86a4SJeremy Kemp         cl_uint n = 0;
2942*6fee86a4SJeremy Kemp 
2943*6fee86a4SJeremy Kemp         if( platforms == nullptr ) {
2944*6fee86a4SJeremy Kemp             return detail::errHandler(CL_INVALID_ARG_VALUE, __GET_PLATFORM_IDS_ERR);
2945*6fee86a4SJeremy Kemp         }
2946*6fee86a4SJeremy Kemp 
2947*6fee86a4SJeremy Kemp         cl_int err = ::clGetPlatformIDs(0, nullptr, &n);
2948*6fee86a4SJeremy Kemp         if (err != CL_SUCCESS) {
2949*6fee86a4SJeremy Kemp             return detail::errHandler(err, __GET_PLATFORM_IDS_ERR);
2950*6fee86a4SJeremy Kemp         }
2951*6fee86a4SJeremy Kemp 
2952*6fee86a4SJeremy Kemp         vector<cl_platform_id> ids(n);
2953*6fee86a4SJeremy Kemp         err = ::clGetPlatformIDs(n, ids.data(), nullptr);
2954*6fee86a4SJeremy Kemp         if (err != CL_SUCCESS) {
2955*6fee86a4SJeremy Kemp             return detail::errHandler(err, __GET_PLATFORM_IDS_ERR);
2956*6fee86a4SJeremy Kemp         }
2957*6fee86a4SJeremy Kemp 
2958*6fee86a4SJeremy Kemp         if (platforms) {
2959*6fee86a4SJeremy Kemp             platforms->resize(ids.size());
2960*6fee86a4SJeremy Kemp 
2961*6fee86a4SJeremy Kemp             // Platforms don't reference count
2962*6fee86a4SJeremy Kemp             for (size_type i = 0; i < ids.size(); i++) {
2963*6fee86a4SJeremy Kemp                 (*platforms)[i] = Platform(ids[i]);
2964*6fee86a4SJeremy Kemp             }
2965*6fee86a4SJeremy Kemp         }
2966*6fee86a4SJeremy Kemp         return CL_SUCCESS;
2967*6fee86a4SJeremy Kemp     }
2968*6fee86a4SJeremy Kemp 
2969*6fee86a4SJeremy Kemp     /*! \brief Gets the first available platform.
2970*6fee86a4SJeremy Kemp      *
2971*6fee86a4SJeremy Kemp      *  Wraps clGetPlatformIDs(), returning the first result.
2972*6fee86a4SJeremy Kemp      */
get(Platform * platform)2973*6fee86a4SJeremy Kemp     static cl_int get(
2974*6fee86a4SJeremy Kemp         Platform * platform)
2975*6fee86a4SJeremy Kemp     {
2976*6fee86a4SJeremy Kemp         cl_int err;
2977*6fee86a4SJeremy Kemp         Platform default_platform = Platform::getDefault(&err);
2978*6fee86a4SJeremy Kemp         if (platform) {
2979*6fee86a4SJeremy Kemp             *platform = default_platform;
2980*6fee86a4SJeremy Kemp         }
2981*6fee86a4SJeremy Kemp         return err;
2982*6fee86a4SJeremy Kemp     }
2983*6fee86a4SJeremy Kemp 
2984*6fee86a4SJeremy Kemp     /*! \brief Gets the first available platform, returning it by value.
2985*6fee86a4SJeremy Kemp      *
2986*6fee86a4SJeremy Kemp      * \return Returns a valid platform if one is available.
2987*6fee86a4SJeremy Kemp      *         If no platform is available will return a null platform.
2988*6fee86a4SJeremy Kemp      * Throws an exception if no platforms are available
2989*6fee86a4SJeremy Kemp      * or an error condition occurs.
2990*6fee86a4SJeremy Kemp      * Wraps clGetPlatformIDs(), returning the first result.
2991*6fee86a4SJeremy Kemp      */
get(cl_int * errResult=nullptr)2992*6fee86a4SJeremy Kemp     static Platform get(
2993*6fee86a4SJeremy Kemp         cl_int * errResult = nullptr)
2994*6fee86a4SJeremy Kemp     {
2995*6fee86a4SJeremy Kemp         cl_int err;
2996*6fee86a4SJeremy Kemp         Platform default_platform = Platform::getDefault(&err);
2997*6fee86a4SJeremy Kemp         if (errResult) {
2998*6fee86a4SJeremy Kemp             *errResult = err;
2999*6fee86a4SJeremy Kemp         }
3000*6fee86a4SJeremy Kemp         return default_platform;
3001*6fee86a4SJeremy Kemp     }
3002*6fee86a4SJeremy Kemp 
3003*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 120
3004*6fee86a4SJeremy Kemp     //! \brief Wrapper for clUnloadCompiler().
3005*6fee86a4SJeremy Kemp     cl_int
unloadCompiler()3006*6fee86a4SJeremy Kemp     unloadCompiler()
3007*6fee86a4SJeremy Kemp     {
3008*6fee86a4SJeremy Kemp         return ::clUnloadPlatformCompiler(object_);
3009*6fee86a4SJeremy Kemp     }
3010*6fee86a4SJeremy Kemp #endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
3011*6fee86a4SJeremy Kemp }; // class Platform
3012*6fee86a4SJeremy Kemp 
3013*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 120
3014*6fee86a4SJeremy Kemp    //! \brief Wrapper for clCreateSubDevices().
createSubDevices(const cl_device_partition_property * properties,vector<Device> * devices)3015*6fee86a4SJeremy Kemp inline cl_int Device::createSubDevices(const cl_device_partition_property* properties,
3016*6fee86a4SJeremy Kemp                          vector<Device>* devices)
3017*6fee86a4SJeremy Kemp {
3018*6fee86a4SJeremy Kemp     cl_uint n = 0;
3019*6fee86a4SJeremy Kemp     cl_int err = clCreateSubDevices(object_, properties, 0, nullptr, &n);
3020*6fee86a4SJeremy Kemp     if (err != CL_SUCCESS)
3021*6fee86a4SJeremy Kemp     {
3022*6fee86a4SJeremy Kemp         return detail::errHandler(err, __CREATE_SUB_DEVICES_ERR);
3023*6fee86a4SJeremy Kemp     }
3024*6fee86a4SJeremy Kemp 
3025*6fee86a4SJeremy Kemp     vector<cl_device_id> ids(n);
3026*6fee86a4SJeremy Kemp     err = clCreateSubDevices(object_, properties, n, ids.data(), nullptr);
3027*6fee86a4SJeremy Kemp     if (err != CL_SUCCESS)
3028*6fee86a4SJeremy Kemp     {
3029*6fee86a4SJeremy Kemp         return detail::errHandler(err, __CREATE_SUB_DEVICES_ERR);
3030*6fee86a4SJeremy Kemp     }
3031*6fee86a4SJeremy Kemp 
3032*6fee86a4SJeremy Kemp     // Cannot trivially assign because we need to capture intermediates
3033*6fee86a4SJeremy Kemp     // with safe construction
3034*6fee86a4SJeremy Kemp     if (devices)
3035*6fee86a4SJeremy Kemp     {
3036*6fee86a4SJeremy Kemp         devices->resize(ids.size());
3037*6fee86a4SJeremy Kemp 
3038*6fee86a4SJeremy Kemp         // Assign to param, constructing with retain behaviour
3039*6fee86a4SJeremy Kemp         // to correctly capture each underlying CL object
3040*6fee86a4SJeremy Kemp         for (size_type i = 0; i < ids.size(); i++)
3041*6fee86a4SJeremy Kemp         {
3042*6fee86a4SJeremy Kemp             // We do not need to retain because this device is being created
3043*6fee86a4SJeremy Kemp             // by the runtime
3044*6fee86a4SJeremy Kemp             (*devices)[i] = Device(ids[i], false);
3045*6fee86a4SJeremy Kemp         }
3046*6fee86a4SJeremy Kemp     }
3047*6fee86a4SJeremy Kemp 
3048*6fee86a4SJeremy Kemp     return CL_SUCCESS;
3049*6fee86a4SJeremy Kemp }
3050*6fee86a4SJeremy Kemp #endif // defined (CL_HPP_TARGET_OPENCL_VERSION >= 120)
3051*6fee86a4SJeremy Kemp 
3052*6fee86a4SJeremy Kemp #if defined(cl_ext_device_fission)
3053*6fee86a4SJeremy Kemp    //! \brief Wrapper for clCreateSubDevices().
createSubDevices(const cl_device_partition_property_ext * properties,vector<Device> * devices)3054*6fee86a4SJeremy Kemp inline cl_int Device::createSubDevices(const cl_device_partition_property_ext* properties,
3055*6fee86a4SJeremy Kemp                         vector<Device>* devices)
3056*6fee86a4SJeremy Kemp {
3057*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 120
3058*6fee86a4SJeremy Kemp     cl::Device device(object_);
3059*6fee86a4SJeremy Kemp     cl_platform_id platform = device.getInfo<CL_DEVICE_PLATFORM>()();
3060*6fee86a4SJeremy Kemp     CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clCreateSubDevicesEXT);
3061*6fee86a4SJeremy Kemp #endif
3062*6fee86a4SJeremy Kemp #if CL_HPP_MINIMUM_OPENCL_VERSION < 120
3063*6fee86a4SJeremy Kemp     CL_HPP_INIT_CL_EXT_FCN_PTR_(clCreateSubDevicesEXT);
3064*6fee86a4SJeremy Kemp #endif
3065*6fee86a4SJeremy Kemp 
3066*6fee86a4SJeremy Kemp     cl_uint n = 0;
3067*6fee86a4SJeremy Kemp     cl_int err = pfn_clCreateSubDevicesEXT(object_, properties, 0, nullptr, &n);
3068*6fee86a4SJeremy Kemp     if (err != CL_SUCCESS)
3069*6fee86a4SJeremy Kemp     {
3070*6fee86a4SJeremy Kemp         return detail::errHandler(err, __CREATE_SUB_DEVICES_ERR);
3071*6fee86a4SJeremy Kemp     }
3072*6fee86a4SJeremy Kemp 
3073*6fee86a4SJeremy Kemp     vector<cl_device_id> ids(n);
3074*6fee86a4SJeremy Kemp     err =
3075*6fee86a4SJeremy Kemp         pfn_clCreateSubDevicesEXT(object_, properties, n, ids.data(), nullptr);
3076*6fee86a4SJeremy Kemp     if (err != CL_SUCCESS)
3077*6fee86a4SJeremy Kemp     {
3078*6fee86a4SJeremy Kemp         return detail::errHandler(err, __CREATE_SUB_DEVICES_ERR);
3079*6fee86a4SJeremy Kemp     }
3080*6fee86a4SJeremy Kemp     // Cannot trivially assign because we need to capture intermediates
3081*6fee86a4SJeremy Kemp     // with safe construction
3082*6fee86a4SJeremy Kemp     if (devices)
3083*6fee86a4SJeremy Kemp     {
3084*6fee86a4SJeremy Kemp         devices->resize(ids.size());
3085*6fee86a4SJeremy Kemp 
3086*6fee86a4SJeremy Kemp         // Assign to param, constructing with retain behaviour
3087*6fee86a4SJeremy Kemp         // to correctly capture each underlying CL object
3088*6fee86a4SJeremy Kemp         for (size_type i = 0; i < ids.size(); i++)
3089*6fee86a4SJeremy Kemp         {
3090*6fee86a4SJeremy Kemp             // We do not need to retain because this device is being created
3091*6fee86a4SJeremy Kemp             // by the runtime
3092*6fee86a4SJeremy Kemp             (*devices)[i] = Device(ids[i], false);
3093*6fee86a4SJeremy Kemp         }
3094*6fee86a4SJeremy Kemp     }
3095*6fee86a4SJeremy Kemp 
3096*6fee86a4SJeremy Kemp     return CL_SUCCESS;
3097*6fee86a4SJeremy Kemp }
3098*6fee86a4SJeremy Kemp #endif // defined(cl_ext_device_fission)
3099*6fee86a4SJeremy Kemp 
3100*6fee86a4SJeremy Kemp CL_HPP_DEFINE_STATIC_MEMBER_ std::once_flag Platform::default_initialized_;
3101*6fee86a4SJeremy Kemp CL_HPP_DEFINE_STATIC_MEMBER_ Platform Platform::default_;
3102*6fee86a4SJeremy Kemp CL_HPP_DEFINE_STATIC_MEMBER_ cl_int Platform::default_error_ = CL_SUCCESS;
3103*6fee86a4SJeremy Kemp 
3104*6fee86a4SJeremy Kemp 
3105*6fee86a4SJeremy Kemp /**
3106*6fee86a4SJeremy Kemp  * Deprecated APIs for 1.2
3107*6fee86a4SJeremy Kemp  */
3108*6fee86a4SJeremy Kemp #if defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS)
3109*6fee86a4SJeremy Kemp /**
3110*6fee86a4SJeremy Kemp  * Unload the OpenCL compiler.
3111*6fee86a4SJeremy Kemp  * \note Deprecated for OpenCL 1.2. Use Platform::unloadCompiler instead.
3112*6fee86a4SJeremy Kemp  */
3113*6fee86a4SJeremy Kemp inline CL_API_PREFIX__VERSION_1_1_DEPRECATED cl_int
3114*6fee86a4SJeremy Kemp UnloadCompiler() CL_API_SUFFIX__VERSION_1_1_DEPRECATED;
3115*6fee86a4SJeremy Kemp inline cl_int
UnloadCompiler()3116*6fee86a4SJeremy Kemp UnloadCompiler()
3117*6fee86a4SJeremy Kemp {
3118*6fee86a4SJeremy Kemp     return ::clUnloadCompiler();
3119*6fee86a4SJeremy Kemp }
3120*6fee86a4SJeremy Kemp #endif // #if defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS)
3121*6fee86a4SJeremy Kemp 
3122*6fee86a4SJeremy Kemp 
3123*6fee86a4SJeremy Kemp #if defined(cl_ext_image_requirements_info)
3124*6fee86a4SJeremy Kemp enum ImageRequirementsInfoExt : cl_image_requirements_info_ext
3125*6fee86a4SJeremy Kemp {
3126*6fee86a4SJeremy Kemp     RowPitchAlign = CL_IMAGE_REQUIREMENTS_ROW_PITCH_ALIGNMENT_EXT,
3127*6fee86a4SJeremy Kemp     BaseAddAlign = CL_IMAGE_REQUIREMENTS_BASE_ADDRESS_ALIGNMENT_EXT,
3128*6fee86a4SJeremy Kemp     Size = CL_IMAGE_REQUIREMENTS_SIZE_EXT,
3129*6fee86a4SJeremy Kemp     MaxWidth = CL_IMAGE_REQUIREMENTS_MAX_WIDTH_EXT,
3130*6fee86a4SJeremy Kemp     MaxHeight = CL_IMAGE_REQUIREMENTS_MAX_HEIGHT_EXT,
3131*6fee86a4SJeremy Kemp     MaxDepth = CL_IMAGE_REQUIREMENTS_MAX_DEPTH_EXT,
3132*6fee86a4SJeremy Kemp     MaxArraySize = CL_IMAGE_REQUIREMENTS_MAX_ARRAY_SIZE_EXT,
3133*6fee86a4SJeremy Kemp #if defined(cl_ext_image_from_buffer)
3134*6fee86a4SJeremy Kemp     SlicePitchAlign = CL_IMAGE_REQUIREMENTS_SLICE_PITCH_ALIGNMENT_EXT,
3135*6fee86a4SJeremy Kemp #endif
3136*6fee86a4SJeremy Kemp };
3137*6fee86a4SJeremy Kemp 
3138*6fee86a4SJeremy Kemp #endif // cl_ext_image_requirements_info
3139*6fee86a4SJeremy Kemp 
3140*6fee86a4SJeremy Kemp 
3141*6fee86a4SJeremy Kemp /*! \brief Class interface for cl_context.
3142*6fee86a4SJeremy Kemp  *
3143*6fee86a4SJeremy Kemp  *  \note Copies of these objects are shallow, meaning that the copy will refer
3144*6fee86a4SJeremy Kemp  *        to the same underlying cl_context as the original.  For details, see
3145*6fee86a4SJeremy Kemp  *        clRetainContext() and clReleaseContext().
3146*6fee86a4SJeremy Kemp  *
3147*6fee86a4SJeremy Kemp  *  \see cl_context
3148*6fee86a4SJeremy Kemp  */
3149*6fee86a4SJeremy Kemp class Context
3150*6fee86a4SJeremy Kemp     : public detail::Wrapper<cl_context>
3151*6fee86a4SJeremy Kemp {
3152*6fee86a4SJeremy Kemp private:
3153*6fee86a4SJeremy Kemp     static std::once_flag default_initialized_;
3154*6fee86a4SJeremy Kemp     static Context default_;
3155*6fee86a4SJeremy Kemp     static cl_int default_error_;
3156*6fee86a4SJeremy Kemp 
3157*6fee86a4SJeremy Kemp     /*! \brief Create the default context from the default device type in the default platform.
3158*6fee86a4SJeremy Kemp      *
3159*6fee86a4SJeremy Kemp      * This sets @c default_ and @c default_error_. It does not throw
3160*6fee86a4SJeremy Kemp      * @c cl::Error.
3161*6fee86a4SJeremy Kemp      */
makeDefault()3162*6fee86a4SJeremy Kemp     static void makeDefault() {
3163*6fee86a4SJeremy Kemp         /* Throwing an exception from a call_once invocation does not do
3164*6fee86a4SJeremy Kemp          * what we wish, so we catch it and save the error.
3165*6fee86a4SJeremy Kemp          */
3166*6fee86a4SJeremy Kemp #if defined(CL_HPP_ENABLE_EXCEPTIONS)
3167*6fee86a4SJeremy Kemp         try
3168*6fee86a4SJeremy Kemp #endif
3169*6fee86a4SJeremy Kemp         {
3170*6fee86a4SJeremy Kemp #if !defined(__APPLE__) && !defined(__MACOS)
3171*6fee86a4SJeremy Kemp             const Platform &p = Platform::getDefault();
3172*6fee86a4SJeremy Kemp             cl_platform_id defaultPlatform = p();
3173*6fee86a4SJeremy Kemp             cl_context_properties properties[3] = {
3174*6fee86a4SJeremy Kemp                 CL_CONTEXT_PLATFORM, (cl_context_properties)defaultPlatform, 0
3175*6fee86a4SJeremy Kemp             };
3176*6fee86a4SJeremy Kemp #else // #if !defined(__APPLE__) && !defined(__MACOS)
3177*6fee86a4SJeremy Kemp             cl_context_properties *properties = nullptr;
3178*6fee86a4SJeremy Kemp #endif // #if !defined(__APPLE__) && !defined(__MACOS)
3179*6fee86a4SJeremy Kemp 
3180*6fee86a4SJeremy Kemp             default_ = Context(
3181*6fee86a4SJeremy Kemp                 CL_DEVICE_TYPE_DEFAULT,
3182*6fee86a4SJeremy Kemp                 properties,
3183*6fee86a4SJeremy Kemp                 nullptr,
3184*6fee86a4SJeremy Kemp                 nullptr,
3185*6fee86a4SJeremy Kemp                 &default_error_);
3186*6fee86a4SJeremy Kemp         }
3187*6fee86a4SJeremy Kemp #if defined(CL_HPP_ENABLE_EXCEPTIONS)
3188*6fee86a4SJeremy Kemp         catch (cl::Error &e) {
3189*6fee86a4SJeremy Kemp             default_error_ = e.err();
3190*6fee86a4SJeremy Kemp         }
3191*6fee86a4SJeremy Kemp #endif
3192*6fee86a4SJeremy Kemp     }
3193*6fee86a4SJeremy Kemp 
3194*6fee86a4SJeremy Kemp 
3195*6fee86a4SJeremy Kemp     /*! \brief Create the default context from a provided Context.
3196*6fee86a4SJeremy Kemp      *
3197*6fee86a4SJeremy Kemp      * This sets @c default_. It does not throw
3198*6fee86a4SJeremy Kemp      * @c cl::Error.
3199*6fee86a4SJeremy Kemp      */
makeDefaultProvided(const Context & c)3200*6fee86a4SJeremy Kemp     static void makeDefaultProvided(const Context &c) {
3201*6fee86a4SJeremy Kemp         default_ = c;
3202*6fee86a4SJeremy Kemp     }
3203*6fee86a4SJeremy Kemp 
3204*6fee86a4SJeremy Kemp #if defined(cl_ext_image_requirements_info)
3205*6fee86a4SJeremy Kemp     struct ImageRequirementsInfo {
3206*6fee86a4SJeremy Kemp 
ImageRequirementsInfocl::Context::ImageRequirementsInfo3207*6fee86a4SJeremy Kemp         ImageRequirementsInfo(cl_mem_flags f, const cl_mem_properties* properties, const ImageFormat* format, const cl_image_desc* desc)
3208*6fee86a4SJeremy Kemp         {
3209*6fee86a4SJeremy Kemp             flags = f;
3210*6fee86a4SJeremy Kemp             properties = properties;
3211*6fee86a4SJeremy Kemp             image_format = format;
3212*6fee86a4SJeremy Kemp             image_desc = desc;
3213*6fee86a4SJeremy Kemp         }
3214*6fee86a4SJeremy Kemp 
3215*6fee86a4SJeremy Kemp         cl_mem_flags flags = 0;
3216*6fee86a4SJeremy Kemp         const cl_mem_properties* properties;
3217*6fee86a4SJeremy Kemp         const ImageFormat* image_format;
3218*6fee86a4SJeremy Kemp         const cl_image_desc* image_desc;
3219*6fee86a4SJeremy Kemp     };
3220*6fee86a4SJeremy Kemp 
getImageRequirementsInfoExtHelper(const Context & context,const ImageRequirementsInfo & info,cl_image_requirements_info_ext param_name,size_type param_value_size,void * param_value,size_type * param_value_size_ret)3221*6fee86a4SJeremy Kemp     static cl_int getImageRequirementsInfoExtHelper(const Context &context,
3222*6fee86a4SJeremy Kemp         const ImageRequirementsInfo &info,
3223*6fee86a4SJeremy Kemp         cl_image_requirements_info_ext param_name,
3224*6fee86a4SJeremy Kemp         size_type param_value_size,
3225*6fee86a4SJeremy Kemp         void* param_value,
3226*6fee86a4SJeremy Kemp         size_type* param_value_size_ret)
3227*6fee86a4SJeremy Kemp     {
3228*6fee86a4SJeremy Kemp 
3229*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 120
3230*6fee86a4SJeremy Kemp         Device device = context.getInfo<CL_CONTEXT_DEVICES>().at(0);
3231*6fee86a4SJeremy Kemp         cl_platform_id platform = device.getInfo<CL_DEVICE_PLATFORM>()();
3232*6fee86a4SJeremy Kemp         CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clGetImageRequirementsInfoEXT);
3233*6fee86a4SJeremy Kemp #else
3234*6fee86a4SJeremy Kemp         CL_HPP_INIT_CL_EXT_FCN_PTR_(clGetImageRequirementsInfoEXT);
3235*6fee86a4SJeremy Kemp #endif
3236*6fee86a4SJeremy Kemp 
3237*6fee86a4SJeremy Kemp         if (pfn_clGetImageRequirementsInfoEXT == nullptr) {
3238*6fee86a4SJeremy Kemp             return detail::errHandler(CL_INVALID_OPERATION, __GET_IMAGE_REQUIREMENT_INFO_EXT_ERR);
3239*6fee86a4SJeremy Kemp         }
3240*6fee86a4SJeremy Kemp 
3241*6fee86a4SJeremy Kemp         return detail::errHandler(
3242*6fee86a4SJeremy Kemp             pfn_clGetImageRequirementsInfoEXT(context(), info.properties,
3243*6fee86a4SJeremy Kemp                 info.flags, info.image_format, info.image_desc, param_name,
3244*6fee86a4SJeremy Kemp                 param_value_size, param_value, param_value_size_ret),
3245*6fee86a4SJeremy Kemp             __GET_IMAGE_REQUIREMENT_INFO_EXT_ERR);
3246*6fee86a4SJeremy Kemp     }
3247*6fee86a4SJeremy Kemp #endif // cl_ext_image_requirements_info
3248*6fee86a4SJeremy Kemp 
3249*6fee86a4SJeremy Kemp public:
3250*6fee86a4SJeremy Kemp #ifdef CL_HPP_UNIT_TEST_ENABLE
3251*6fee86a4SJeremy Kemp     /*! \brief Reset the default.
3252*6fee86a4SJeremy Kemp     *
3253*6fee86a4SJeremy Kemp     * This sets @c default_ to an empty value to support cleanup in
3254*6fee86a4SJeremy Kemp     * the unit test framework.
3255*6fee86a4SJeremy Kemp     * This function is not thread safe.
3256*6fee86a4SJeremy Kemp     */
unitTestClearDefault()3257*6fee86a4SJeremy Kemp     static void unitTestClearDefault() {
3258*6fee86a4SJeremy Kemp         default_ = Context();
3259*6fee86a4SJeremy Kemp     }
3260*6fee86a4SJeremy Kemp #endif // #ifdef CL_HPP_UNIT_TEST_ENABLE
3261*6fee86a4SJeremy Kemp 
3262*6fee86a4SJeremy Kemp     /*! \brief Constructs a context including a list of specified devices.
3263*6fee86a4SJeremy Kemp      *
3264*6fee86a4SJeremy Kemp      *  Wraps clCreateContext().
3265*6fee86a4SJeremy Kemp      */
Context(const vector<Device> & devices,const cl_context_properties * properties=nullptr,void (CL_CALLBACK * notifyFptr)(const char *,const void *,size_type,void *)=nullptr,void * data=nullptr,cl_int * err=nullptr)3266*6fee86a4SJeremy Kemp     Context(
3267*6fee86a4SJeremy Kemp         const vector<Device>& devices,
3268*6fee86a4SJeremy Kemp         const cl_context_properties* properties = nullptr,
3269*6fee86a4SJeremy Kemp         void (CL_CALLBACK * notifyFptr)(
3270*6fee86a4SJeremy Kemp             const char *,
3271*6fee86a4SJeremy Kemp             const void *,
3272*6fee86a4SJeremy Kemp             size_type,
3273*6fee86a4SJeremy Kemp             void *) = nullptr,
3274*6fee86a4SJeremy Kemp         void* data = nullptr,
3275*6fee86a4SJeremy Kemp         cl_int* err = nullptr)
3276*6fee86a4SJeremy Kemp     {
3277*6fee86a4SJeremy Kemp         cl_int error;
3278*6fee86a4SJeremy Kemp 
3279*6fee86a4SJeremy Kemp         size_type numDevices = devices.size();
3280*6fee86a4SJeremy Kemp         vector<cl_device_id> deviceIDs(numDevices);
3281*6fee86a4SJeremy Kemp 
3282*6fee86a4SJeremy Kemp         for( size_type deviceIndex = 0; deviceIndex < numDevices; ++deviceIndex ) {
3283*6fee86a4SJeremy Kemp             deviceIDs[deviceIndex] = (devices[deviceIndex])();
3284*6fee86a4SJeremy Kemp         }
3285*6fee86a4SJeremy Kemp 
3286*6fee86a4SJeremy Kemp         object_ = ::clCreateContext(
3287*6fee86a4SJeremy Kemp             properties, (cl_uint) numDevices,
3288*6fee86a4SJeremy Kemp             deviceIDs.data(),
3289*6fee86a4SJeremy Kemp             notifyFptr, data, &error);
3290*6fee86a4SJeremy Kemp 
3291*6fee86a4SJeremy Kemp         detail::errHandler(error, __CREATE_CONTEXT_ERR);
3292*6fee86a4SJeremy Kemp         if (err != nullptr) {
3293*6fee86a4SJeremy Kemp             *err = error;
3294*6fee86a4SJeremy Kemp         }
3295*6fee86a4SJeremy Kemp     }
3296*6fee86a4SJeremy Kemp 
3297*6fee86a4SJeremy Kemp     /*! \brief Constructs a context including a specific device.
3298*6fee86a4SJeremy Kemp      *
3299*6fee86a4SJeremy Kemp      *  Wraps clCreateContext().
3300*6fee86a4SJeremy Kemp      */
Context(const Device & device,const cl_context_properties * properties=nullptr,void (CL_CALLBACK * notifyFptr)(const char *,const void *,size_type,void *)=nullptr,void * data=nullptr,cl_int * err=nullptr)3301*6fee86a4SJeremy Kemp     Context(
3302*6fee86a4SJeremy Kemp         const Device& device,
3303*6fee86a4SJeremy Kemp         const cl_context_properties* properties = nullptr,
3304*6fee86a4SJeremy Kemp         void (CL_CALLBACK * notifyFptr)(
3305*6fee86a4SJeremy Kemp             const char *,
3306*6fee86a4SJeremy Kemp             const void *,
3307*6fee86a4SJeremy Kemp             size_type,
3308*6fee86a4SJeremy Kemp             void *) = nullptr,
3309*6fee86a4SJeremy Kemp         void* data = nullptr,
3310*6fee86a4SJeremy Kemp         cl_int* err = nullptr)
3311*6fee86a4SJeremy Kemp     {
3312*6fee86a4SJeremy Kemp         cl_int error;
3313*6fee86a4SJeremy Kemp 
3314*6fee86a4SJeremy Kemp         cl_device_id deviceID = device();
3315*6fee86a4SJeremy Kemp 
3316*6fee86a4SJeremy Kemp         object_ = ::clCreateContext(
3317*6fee86a4SJeremy Kemp             properties, 1,
3318*6fee86a4SJeremy Kemp             &deviceID,
3319*6fee86a4SJeremy Kemp             notifyFptr, data, &error);
3320*6fee86a4SJeremy Kemp 
3321*6fee86a4SJeremy Kemp         detail::errHandler(error, __CREATE_CONTEXT_ERR);
3322*6fee86a4SJeremy Kemp         if (err != nullptr) {
3323*6fee86a4SJeremy Kemp             *err = error;
3324*6fee86a4SJeremy Kemp         }
3325*6fee86a4SJeremy Kemp     }
3326*6fee86a4SJeremy Kemp 
3327*6fee86a4SJeremy Kemp     /*! \brief Constructs a context including all or a subset of devices of a specified type.
3328*6fee86a4SJeremy Kemp      *
3329*6fee86a4SJeremy Kemp      *  Wraps clCreateContextFromType().
3330*6fee86a4SJeremy Kemp      */
Context(cl_device_type type,const cl_context_properties * properties=nullptr,void (CL_CALLBACK * notifyFptr)(const char *,const void *,size_type,void *)=nullptr,void * data=nullptr,cl_int * err=nullptr)3331*6fee86a4SJeremy Kemp     Context(
3332*6fee86a4SJeremy Kemp         cl_device_type type,
3333*6fee86a4SJeremy Kemp         const cl_context_properties* properties = nullptr,
3334*6fee86a4SJeremy Kemp         void (CL_CALLBACK * notifyFptr)(
3335*6fee86a4SJeremy Kemp             const char *,
3336*6fee86a4SJeremy Kemp             const void *,
3337*6fee86a4SJeremy Kemp             size_type,
3338*6fee86a4SJeremy Kemp             void *) = nullptr,
3339*6fee86a4SJeremy Kemp         void* data = nullptr,
3340*6fee86a4SJeremy Kemp         cl_int* err = nullptr)
3341*6fee86a4SJeremy Kemp     {
3342*6fee86a4SJeremy Kemp         cl_int error;
3343*6fee86a4SJeremy Kemp 
3344*6fee86a4SJeremy Kemp #if !defined(__APPLE__) && !defined(__MACOS)
3345*6fee86a4SJeremy Kemp         cl_context_properties prop[4] = {CL_CONTEXT_PLATFORM, 0, 0, 0 };
3346*6fee86a4SJeremy Kemp 
3347*6fee86a4SJeremy Kemp         if (properties == nullptr) {
3348*6fee86a4SJeremy Kemp             // Get a valid platform ID as we cannot send in a blank one
3349*6fee86a4SJeremy Kemp             vector<Platform> platforms;
3350*6fee86a4SJeremy Kemp             error = Platform::get(&platforms);
3351*6fee86a4SJeremy Kemp             if (error != CL_SUCCESS) {
3352*6fee86a4SJeremy Kemp                 detail::errHandler(error, __CREATE_CONTEXT_FROM_TYPE_ERR);
3353*6fee86a4SJeremy Kemp                 if (err != nullptr) {
3354*6fee86a4SJeremy Kemp                     *err = error;
3355*6fee86a4SJeremy Kemp                 }
3356*6fee86a4SJeremy Kemp                 return;
3357*6fee86a4SJeremy Kemp             }
3358*6fee86a4SJeremy Kemp 
3359*6fee86a4SJeremy Kemp             // Check the platforms we found for a device of our specified type
3360*6fee86a4SJeremy Kemp             cl_context_properties platform_id = 0;
3361*6fee86a4SJeremy Kemp             for (unsigned int i = 0; i < platforms.size(); i++) {
3362*6fee86a4SJeremy Kemp 
3363*6fee86a4SJeremy Kemp                 vector<Device> devices;
3364*6fee86a4SJeremy Kemp 
3365*6fee86a4SJeremy Kemp #if defined(CL_HPP_ENABLE_EXCEPTIONS)
3366*6fee86a4SJeremy Kemp                 try {
3367*6fee86a4SJeremy Kemp #endif
3368*6fee86a4SJeremy Kemp 
3369*6fee86a4SJeremy Kemp                     error = platforms[i].getDevices(type, &devices);
3370*6fee86a4SJeremy Kemp 
3371*6fee86a4SJeremy Kemp #if defined(CL_HPP_ENABLE_EXCEPTIONS)
3372*6fee86a4SJeremy Kemp                 } catch (cl::Error& e) {
3373*6fee86a4SJeremy Kemp                     error = e.err();
3374*6fee86a4SJeremy Kemp                 }
3375*6fee86a4SJeremy Kemp     // Catch if exceptions are enabled as we don't want to exit if first platform has no devices of type
3376*6fee86a4SJeremy Kemp     // We do error checking next anyway, and can throw there if needed
3377*6fee86a4SJeremy Kemp #endif
3378*6fee86a4SJeremy Kemp 
3379*6fee86a4SJeremy Kemp                 // Only squash CL_SUCCESS and CL_DEVICE_NOT_FOUND
3380*6fee86a4SJeremy Kemp                 if (error != CL_SUCCESS && error != CL_DEVICE_NOT_FOUND) {
3381*6fee86a4SJeremy Kemp                     detail::errHandler(error, __CREATE_CONTEXT_FROM_TYPE_ERR);
3382*6fee86a4SJeremy Kemp                     if (err != nullptr) {
3383*6fee86a4SJeremy Kemp                         *err = error;
3384*6fee86a4SJeremy Kemp                     }
3385*6fee86a4SJeremy Kemp                 }
3386*6fee86a4SJeremy Kemp 
3387*6fee86a4SJeremy Kemp                 if (devices.size() > 0) {
3388*6fee86a4SJeremy Kemp                     platform_id = (cl_context_properties)platforms[i]();
3389*6fee86a4SJeremy Kemp                     break;
3390*6fee86a4SJeremy Kemp                 }
3391*6fee86a4SJeremy Kemp             }
3392*6fee86a4SJeremy Kemp 
3393*6fee86a4SJeremy Kemp             if (platform_id == 0) {
3394*6fee86a4SJeremy Kemp                 detail::errHandler(CL_DEVICE_NOT_FOUND, __CREATE_CONTEXT_FROM_TYPE_ERR);
3395*6fee86a4SJeremy Kemp                 if (err != nullptr) {
3396*6fee86a4SJeremy Kemp                     *err = CL_DEVICE_NOT_FOUND;
3397*6fee86a4SJeremy Kemp                 }
3398*6fee86a4SJeremy Kemp                 return;
3399*6fee86a4SJeremy Kemp             }
3400*6fee86a4SJeremy Kemp 
3401*6fee86a4SJeremy Kemp             prop[1] = platform_id;
3402*6fee86a4SJeremy Kemp             properties = &prop[0];
3403*6fee86a4SJeremy Kemp         }
3404*6fee86a4SJeremy Kemp #endif
3405*6fee86a4SJeremy Kemp         object_ = ::clCreateContextFromType(
3406*6fee86a4SJeremy Kemp             properties, type, notifyFptr, data, &error);
3407*6fee86a4SJeremy Kemp 
3408*6fee86a4SJeremy Kemp         detail::errHandler(error, __CREATE_CONTEXT_FROM_TYPE_ERR);
3409*6fee86a4SJeremy Kemp         if (err != nullptr) {
3410*6fee86a4SJeremy Kemp             *err = error;
3411*6fee86a4SJeremy Kemp         }
3412*6fee86a4SJeremy Kemp     }
3413*6fee86a4SJeremy Kemp 
3414*6fee86a4SJeremy Kemp 
3415*6fee86a4SJeremy Kemp     /*! \brief Returns a singleton context including all devices of CL_DEVICE_TYPE_DEFAULT.
3416*6fee86a4SJeremy Kemp      *
3417*6fee86a4SJeremy Kemp      *  \note All calls to this function return the same cl_context as the first.
3418*6fee86a4SJeremy Kemp      */
getDefault(cl_int * err=nullptr)3419*6fee86a4SJeremy Kemp     static Context getDefault(cl_int * err = nullptr)
3420*6fee86a4SJeremy Kemp     {
3421*6fee86a4SJeremy Kemp         std::call_once(default_initialized_, makeDefault);
3422*6fee86a4SJeremy Kemp         detail::errHandler(default_error_);
3423*6fee86a4SJeremy Kemp         if (err != nullptr) {
3424*6fee86a4SJeremy Kemp             *err = default_error_;
3425*6fee86a4SJeremy Kemp         }
3426*6fee86a4SJeremy Kemp         return default_;
3427*6fee86a4SJeremy Kemp     }
3428*6fee86a4SJeremy Kemp 
3429*6fee86a4SJeremy Kemp     /**
3430*6fee86a4SJeremy Kemp      * Modify the default context to be used by
3431*6fee86a4SJeremy Kemp      * subsequent operations.
3432*6fee86a4SJeremy Kemp      * Will only set the default if no default was previously created.
3433*6fee86a4SJeremy Kemp      * @return updated default context.
3434*6fee86a4SJeremy Kemp      *         Should be compared to the passed value to ensure that it was updated.
3435*6fee86a4SJeremy Kemp      */
setDefault(const Context & default_context)3436*6fee86a4SJeremy Kemp     static Context setDefault(const Context &default_context)
3437*6fee86a4SJeremy Kemp     {
3438*6fee86a4SJeremy Kemp         std::call_once(default_initialized_, makeDefaultProvided, std::cref(default_context));
3439*6fee86a4SJeremy Kemp         detail::errHandler(default_error_);
3440*6fee86a4SJeremy Kemp         return default_;
3441*6fee86a4SJeremy Kemp     }
3442*6fee86a4SJeremy Kemp 
3443*6fee86a4SJeremy Kemp     //! \brief Default constructor - initializes to nullptr.
Context()3444*6fee86a4SJeremy Kemp     Context() : detail::Wrapper<cl_type>() { }
3445*6fee86a4SJeremy Kemp 
3446*6fee86a4SJeremy Kemp     /*! \brief Constructor from cl_context - takes ownership.
3447*6fee86a4SJeremy Kemp      *
3448*6fee86a4SJeremy Kemp      *  This effectively transfers ownership of a refcount on the cl_context
3449*6fee86a4SJeremy Kemp      *  into the new Context object.
3450*6fee86a4SJeremy Kemp      */
Context(const cl_context & context,bool retainObject=false)3451*6fee86a4SJeremy Kemp     explicit Context(const cl_context& context, bool retainObject = false) :
3452*6fee86a4SJeremy Kemp         detail::Wrapper<cl_type>(context, retainObject) { }
3453*6fee86a4SJeremy Kemp 
3454*6fee86a4SJeremy Kemp     /*! \brief Assignment operator from cl_context - takes ownership.
3455*6fee86a4SJeremy Kemp      *
3456*6fee86a4SJeremy Kemp      *  This effectively transfers ownership of a refcount on the rhs and calls
3457*6fee86a4SJeremy Kemp      *  clReleaseContext() on the value previously held by this instance.
3458*6fee86a4SJeremy Kemp      */
operator =(const cl_context & rhs)3459*6fee86a4SJeremy Kemp     Context& operator = (const cl_context& rhs)
3460*6fee86a4SJeremy Kemp     {
3461*6fee86a4SJeremy Kemp         detail::Wrapper<cl_type>::operator=(rhs);
3462*6fee86a4SJeremy Kemp         return *this;
3463*6fee86a4SJeremy Kemp     }
3464*6fee86a4SJeremy Kemp 
3465*6fee86a4SJeremy Kemp     //! \brief Wrapper for clGetContextInfo().
3466*6fee86a4SJeremy Kemp     template <typename T>
getInfo(cl_context_info name,T * param) const3467*6fee86a4SJeremy Kemp     cl_int getInfo(cl_context_info name, T* param) const
3468*6fee86a4SJeremy Kemp     {
3469*6fee86a4SJeremy Kemp         return detail::errHandler(
3470*6fee86a4SJeremy Kemp             detail::getInfo(&::clGetContextInfo, object_, name, param),
3471*6fee86a4SJeremy Kemp             __GET_CONTEXT_INFO_ERR);
3472*6fee86a4SJeremy Kemp     }
3473*6fee86a4SJeremy Kemp 
3474*6fee86a4SJeremy Kemp     //! \brief Wrapper for clGetContextInfo() that returns by value.
3475*6fee86a4SJeremy Kemp     template <cl_context_info name> typename
3476*6fee86a4SJeremy Kemp     detail::param_traits<detail::cl_context_info, name>::param_type
getInfo(cl_int * err=nullptr) const3477*6fee86a4SJeremy Kemp     getInfo(cl_int* err = nullptr) const
3478*6fee86a4SJeremy Kemp     {
3479*6fee86a4SJeremy Kemp         typename detail::param_traits<
3480*6fee86a4SJeremy Kemp             detail::cl_context_info, name>::param_type param;
3481*6fee86a4SJeremy Kemp         cl_int result = getInfo(name, &param);
3482*6fee86a4SJeremy Kemp         if (err != nullptr) {
3483*6fee86a4SJeremy Kemp             *err = result;
3484*6fee86a4SJeremy Kemp         }
3485*6fee86a4SJeremy Kemp         return param;
3486*6fee86a4SJeremy Kemp     }
3487*6fee86a4SJeremy Kemp 
3488*6fee86a4SJeremy Kemp     /*! \brief Gets a list of supported image formats.
3489*6fee86a4SJeremy Kemp      *
3490*6fee86a4SJeremy Kemp      *  Wraps clGetSupportedImageFormats().
3491*6fee86a4SJeremy Kemp      */
getSupportedImageFormats(cl_mem_flags flags,cl_mem_object_type type,vector<ImageFormat> * formats) const3492*6fee86a4SJeremy Kemp     cl_int getSupportedImageFormats(
3493*6fee86a4SJeremy Kemp         cl_mem_flags flags,
3494*6fee86a4SJeremy Kemp         cl_mem_object_type type,
3495*6fee86a4SJeremy Kemp         vector<ImageFormat>* formats) const
3496*6fee86a4SJeremy Kemp     {
3497*6fee86a4SJeremy Kemp         cl_uint numEntries;
3498*6fee86a4SJeremy Kemp 
3499*6fee86a4SJeremy Kemp         if (!formats) {
3500*6fee86a4SJeremy Kemp             return CL_SUCCESS;
3501*6fee86a4SJeremy Kemp         }
3502*6fee86a4SJeremy Kemp 
3503*6fee86a4SJeremy Kemp         cl_int err = ::clGetSupportedImageFormats(
3504*6fee86a4SJeremy Kemp            object_,
3505*6fee86a4SJeremy Kemp            flags,
3506*6fee86a4SJeremy Kemp            type,
3507*6fee86a4SJeremy Kemp            0,
3508*6fee86a4SJeremy Kemp            nullptr,
3509*6fee86a4SJeremy Kemp            &numEntries);
3510*6fee86a4SJeremy Kemp         if (err != CL_SUCCESS) {
3511*6fee86a4SJeremy Kemp             return detail::errHandler(err, __GET_SUPPORTED_IMAGE_FORMATS_ERR);
3512*6fee86a4SJeremy Kemp         }
3513*6fee86a4SJeremy Kemp 
3514*6fee86a4SJeremy Kemp         if (numEntries > 0) {
3515*6fee86a4SJeremy Kemp             vector<ImageFormat> value(numEntries);
3516*6fee86a4SJeremy Kemp             err = ::clGetSupportedImageFormats(
3517*6fee86a4SJeremy Kemp                 object_,
3518*6fee86a4SJeremy Kemp                 flags,
3519*6fee86a4SJeremy Kemp                 type,
3520*6fee86a4SJeremy Kemp                 numEntries,
3521*6fee86a4SJeremy Kemp                 (cl_image_format*)value.data(),
3522*6fee86a4SJeremy Kemp                 nullptr);
3523*6fee86a4SJeremy Kemp             if (err != CL_SUCCESS) {
3524*6fee86a4SJeremy Kemp                 return detail::errHandler(err, __GET_SUPPORTED_IMAGE_FORMATS_ERR);
3525*6fee86a4SJeremy Kemp             }
3526*6fee86a4SJeremy Kemp 
3527*6fee86a4SJeremy Kemp             formats->assign(value.begin(), value.end());
3528*6fee86a4SJeremy Kemp         }
3529*6fee86a4SJeremy Kemp         else {
3530*6fee86a4SJeremy Kemp             // If no values are being returned, ensure an empty vector comes back
3531*6fee86a4SJeremy Kemp             formats->clear();
3532*6fee86a4SJeremy Kemp         }
3533*6fee86a4SJeremy Kemp 
3534*6fee86a4SJeremy Kemp         return CL_SUCCESS;
3535*6fee86a4SJeremy Kemp     }
3536*6fee86a4SJeremy Kemp 
3537*6fee86a4SJeremy Kemp #if defined(cl_ext_image_requirements_info)
3538*6fee86a4SJeremy Kemp     template <typename T>
getImageRequirementsInfoExt(cl_image_requirements_info_ext name,T * param,cl_mem_flags flags=0,const cl_mem_properties * properties=nullptr,const ImageFormat * image_format=nullptr,const cl_image_desc * image_desc=nullptr) const3539*6fee86a4SJeremy Kemp     cl_int getImageRequirementsInfoExt(cl_image_requirements_info_ext name,
3540*6fee86a4SJeremy Kemp         T* param,
3541*6fee86a4SJeremy Kemp         cl_mem_flags flags = 0,
3542*6fee86a4SJeremy Kemp         const cl_mem_properties* properties = nullptr,
3543*6fee86a4SJeremy Kemp         const ImageFormat* image_format = nullptr,
3544*6fee86a4SJeremy Kemp         const cl_image_desc* image_desc = nullptr) const
3545*6fee86a4SJeremy Kemp     {
3546*6fee86a4SJeremy Kemp         ImageRequirementsInfo imageInfo = {flags, properties, image_format, image_desc};
3547*6fee86a4SJeremy Kemp 
3548*6fee86a4SJeremy Kemp         return detail::errHandler(
3549*6fee86a4SJeremy Kemp             detail::getInfo(
3550*6fee86a4SJeremy Kemp                 Context::getImageRequirementsInfoExtHelper, *this, imageInfo, name, param),
3551*6fee86a4SJeremy Kemp                 __GET_IMAGE_REQUIREMENT_INFO_EXT_ERR);
3552*6fee86a4SJeremy Kemp     }
3553*6fee86a4SJeremy Kemp 
3554*6fee86a4SJeremy Kemp     template <cl_image_requirements_info_ext type> typename
3555*6fee86a4SJeremy Kemp     detail::param_traits<detail::cl_image_requirements_info_ext, type>::param_type
getImageRequirementsInfoExt(cl_mem_flags flags=0,const cl_mem_properties * properties=nullptr,const ImageFormat * image_format=nullptr,const cl_image_desc * image_desc=nullptr,cl_int * err=nullptr) const3556*6fee86a4SJeremy Kemp         getImageRequirementsInfoExt(cl_mem_flags flags = 0,
3557*6fee86a4SJeremy Kemp             const cl_mem_properties* properties = nullptr,
3558*6fee86a4SJeremy Kemp             const ImageFormat* image_format = nullptr,
3559*6fee86a4SJeremy Kemp             const cl_image_desc* image_desc = nullptr,
3560*6fee86a4SJeremy Kemp             cl_int* err = nullptr) const
3561*6fee86a4SJeremy Kemp     {
3562*6fee86a4SJeremy Kemp         typename detail::param_traits<
3563*6fee86a4SJeremy Kemp         detail::cl_image_requirements_info_ext, type>::param_type param;
3564*6fee86a4SJeremy Kemp         cl_int result = getImageRequirementsInfoExt(type, &param, flags, properties, image_format, image_desc);
3565*6fee86a4SJeremy Kemp         if (err != nullptr) {
3566*6fee86a4SJeremy Kemp             *err = result;
3567*6fee86a4SJeremy Kemp         }
3568*6fee86a4SJeremy Kemp         return param;
3569*6fee86a4SJeremy Kemp     }
3570*6fee86a4SJeremy Kemp #endif // cl_ext_image_requirements_info
3571*6fee86a4SJeremy Kemp 
3572*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 300
3573*6fee86a4SJeremy Kemp     /*! \brief  Registers a destructor callback function with a context.
3574*6fee86a4SJeremy Kemp      *
3575*6fee86a4SJeremy Kemp      *  Wraps clSetContextDestructorCallback().
3576*6fee86a4SJeremy Kemp      *
3577*6fee86a4SJeremy Kemp      * Each call to this function registers the specified callback function on
3578*6fee86a4SJeremy Kemp      * a destructor callback stack associated with context. The registered
3579*6fee86a4SJeremy Kemp      * callback functions are called in the reverse order in which they were registered.
3580*6fee86a4SJeremy Kemp      * If a context callback function was specified when context was created,
3581*6fee86a4SJeremy Kemp      * it will not be called after any context destructor callback is called.
3582*6fee86a4SJeremy Kemp      */
setDestructorCallback(void (CL_CALLBACK * pfn_notify)(cl_context,void *),void * user_data=nullptr)3583*6fee86a4SJeremy Kemp     cl_int setDestructorCallback(
3584*6fee86a4SJeremy Kemp         void (CL_CALLBACK * pfn_notify)(cl_context, void *),
3585*6fee86a4SJeremy Kemp         void * user_data = nullptr)
3586*6fee86a4SJeremy Kemp     {
3587*6fee86a4SJeremy Kemp         return detail::errHandler(
3588*6fee86a4SJeremy Kemp             ::clSetContextDestructorCallback(
3589*6fee86a4SJeremy Kemp                 object_,
3590*6fee86a4SJeremy Kemp                 pfn_notify,
3591*6fee86a4SJeremy Kemp                 user_data),
3592*6fee86a4SJeremy Kemp                 __SET_CONTEXT_DESCTRUCTOR_CALLBACK_ERR);
3593*6fee86a4SJeremy Kemp     }
3594*6fee86a4SJeremy Kemp #endif // CL_HPP_TARGET_OPENCL_VERSION >= 300
3595*6fee86a4SJeremy Kemp };
3596*6fee86a4SJeremy Kemp 
makeDefault()3597*6fee86a4SJeremy Kemp inline void Device::makeDefault()
3598*6fee86a4SJeremy Kemp {
3599*6fee86a4SJeremy Kemp     /* Throwing an exception from a call_once invocation does not do
3600*6fee86a4SJeremy Kemp     * what we wish, so we catch it and save the error.
3601*6fee86a4SJeremy Kemp     */
3602*6fee86a4SJeremy Kemp #if defined(CL_HPP_ENABLE_EXCEPTIONS)
3603*6fee86a4SJeremy Kemp     try
3604*6fee86a4SJeremy Kemp #endif
3605*6fee86a4SJeremy Kemp     {
3606*6fee86a4SJeremy Kemp         cl_int error = 0;
3607*6fee86a4SJeremy Kemp 
3608*6fee86a4SJeremy Kemp         Context context = Context::getDefault(&error);
3609*6fee86a4SJeremy Kemp         detail::errHandler(error, __CREATE_CONTEXT_ERR);
3610*6fee86a4SJeremy Kemp 
3611*6fee86a4SJeremy Kemp         if (error != CL_SUCCESS) {
3612*6fee86a4SJeremy Kemp             default_error_ = error;
3613*6fee86a4SJeremy Kemp         }
3614*6fee86a4SJeremy Kemp         else {
3615*6fee86a4SJeremy Kemp             default_ = context.getInfo<CL_CONTEXT_DEVICES>()[0];
3616*6fee86a4SJeremy Kemp             default_error_ = CL_SUCCESS;
3617*6fee86a4SJeremy Kemp         }
3618*6fee86a4SJeremy Kemp     }
3619*6fee86a4SJeremy Kemp #if defined(CL_HPP_ENABLE_EXCEPTIONS)
3620*6fee86a4SJeremy Kemp     catch (cl::Error &e) {
3621*6fee86a4SJeremy Kemp         default_error_ = e.err();
3622*6fee86a4SJeremy Kemp     }
3623*6fee86a4SJeremy Kemp #endif
3624*6fee86a4SJeremy Kemp }
3625*6fee86a4SJeremy Kemp 
3626*6fee86a4SJeremy Kemp CL_HPP_DEFINE_STATIC_MEMBER_ std::once_flag Context::default_initialized_;
3627*6fee86a4SJeremy Kemp CL_HPP_DEFINE_STATIC_MEMBER_ Context Context::default_;
3628*6fee86a4SJeremy Kemp CL_HPP_DEFINE_STATIC_MEMBER_ cl_int Context::default_error_ = CL_SUCCESS;
3629*6fee86a4SJeremy Kemp 
3630*6fee86a4SJeremy Kemp /*! \brief Class interface for cl_event.
3631*6fee86a4SJeremy Kemp  *
3632*6fee86a4SJeremy Kemp  *  \note Copies of these objects are shallow, meaning that the copy will refer
3633*6fee86a4SJeremy Kemp  *        to the same underlying cl_event as the original.  For details, see
3634*6fee86a4SJeremy Kemp  *        clRetainEvent() and clReleaseEvent().
3635*6fee86a4SJeremy Kemp  *
3636*6fee86a4SJeremy Kemp  *  \see cl_event
3637*6fee86a4SJeremy Kemp  */
3638*6fee86a4SJeremy Kemp class Event : public detail::Wrapper<cl_event>
3639*6fee86a4SJeremy Kemp {
3640*6fee86a4SJeremy Kemp public:
3641*6fee86a4SJeremy Kemp     //! \brief Default constructor - initializes to nullptr.
Event()3642*6fee86a4SJeremy Kemp     Event() : detail::Wrapper<cl_type>() { }
3643*6fee86a4SJeremy Kemp 
3644*6fee86a4SJeremy Kemp     /*! \brief Constructor from cl_event - takes ownership.
3645*6fee86a4SJeremy Kemp      *
3646*6fee86a4SJeremy Kemp      * \param retainObject will cause the constructor to retain its cl object.
3647*6fee86a4SJeremy Kemp      *                     Defaults to false to maintain compatibility with
3648*6fee86a4SJeremy Kemp      *                     earlier versions.
3649*6fee86a4SJeremy Kemp      *  This effectively transfers ownership of a refcount on the cl_event
3650*6fee86a4SJeremy Kemp      *  into the new Event object.
3651*6fee86a4SJeremy Kemp      */
Event(const cl_event & event,bool retainObject=false)3652*6fee86a4SJeremy Kemp     explicit Event(const cl_event& event, bool retainObject = false) :
3653*6fee86a4SJeremy Kemp         detail::Wrapper<cl_type>(event, retainObject) { }
3654*6fee86a4SJeremy Kemp 
3655*6fee86a4SJeremy Kemp     /*! \brief Assignment operator from cl_event - takes ownership.
3656*6fee86a4SJeremy Kemp      *
3657*6fee86a4SJeremy Kemp      *  This effectively transfers ownership of a refcount on the rhs and calls
3658*6fee86a4SJeremy Kemp      *  clReleaseEvent() on the value previously held by this instance.
3659*6fee86a4SJeremy Kemp      */
operator =(const cl_event & rhs)3660*6fee86a4SJeremy Kemp     Event& operator = (const cl_event& rhs)
3661*6fee86a4SJeremy Kemp     {
3662*6fee86a4SJeremy Kemp         detail::Wrapper<cl_type>::operator=(rhs);
3663*6fee86a4SJeremy Kemp         return *this;
3664*6fee86a4SJeremy Kemp     }
3665*6fee86a4SJeremy Kemp 
3666*6fee86a4SJeremy Kemp     //! \brief Wrapper for clGetEventInfo().
3667*6fee86a4SJeremy Kemp     template <typename T>
getInfo(cl_event_info name,T * param) const3668*6fee86a4SJeremy Kemp     cl_int getInfo(cl_event_info name, T* param) const
3669*6fee86a4SJeremy Kemp     {
3670*6fee86a4SJeremy Kemp         return detail::errHandler(
3671*6fee86a4SJeremy Kemp             detail::getInfo(&::clGetEventInfo, object_, name, param),
3672*6fee86a4SJeremy Kemp             __GET_EVENT_INFO_ERR);
3673*6fee86a4SJeremy Kemp     }
3674*6fee86a4SJeremy Kemp 
3675*6fee86a4SJeremy Kemp     //! \brief Wrapper for clGetEventInfo() that returns by value.
3676*6fee86a4SJeremy Kemp     template <cl_event_info name> typename
3677*6fee86a4SJeremy Kemp     detail::param_traits<detail::cl_event_info, name>::param_type
getInfo(cl_int * err=nullptr) const3678*6fee86a4SJeremy Kemp     getInfo(cl_int* err = nullptr) const
3679*6fee86a4SJeremy Kemp     {
3680*6fee86a4SJeremy Kemp         typename detail::param_traits<
3681*6fee86a4SJeremy Kemp             detail::cl_event_info, name>::param_type param;
3682*6fee86a4SJeremy Kemp         cl_int result = getInfo(name, &param);
3683*6fee86a4SJeremy Kemp         if (err != nullptr) {
3684*6fee86a4SJeremy Kemp             *err = result;
3685*6fee86a4SJeremy Kemp         }
3686*6fee86a4SJeremy Kemp         return param;
3687*6fee86a4SJeremy Kemp     }
3688*6fee86a4SJeremy Kemp 
3689*6fee86a4SJeremy Kemp     //! \brief Wrapper for clGetEventProfilingInfo().
3690*6fee86a4SJeremy Kemp     template <typename T>
getProfilingInfo(cl_profiling_info name,T * param) const3691*6fee86a4SJeremy Kemp     cl_int getProfilingInfo(cl_profiling_info name, T* param) const
3692*6fee86a4SJeremy Kemp     {
3693*6fee86a4SJeremy Kemp         return detail::errHandler(detail::getInfo(
3694*6fee86a4SJeremy Kemp             &::clGetEventProfilingInfo, object_, name, param),
3695*6fee86a4SJeremy Kemp             __GET_EVENT_PROFILE_INFO_ERR);
3696*6fee86a4SJeremy Kemp     }
3697*6fee86a4SJeremy Kemp 
3698*6fee86a4SJeremy Kemp     //! \brief Wrapper for clGetEventProfilingInfo() that returns by value.
3699*6fee86a4SJeremy Kemp     template <cl_profiling_info name> typename
3700*6fee86a4SJeremy Kemp     detail::param_traits<detail::cl_profiling_info, name>::param_type
getProfilingInfo(cl_int * err=nullptr) const3701*6fee86a4SJeremy Kemp     getProfilingInfo(cl_int* err = nullptr) const
3702*6fee86a4SJeremy Kemp     {
3703*6fee86a4SJeremy Kemp         typename detail::param_traits<
3704*6fee86a4SJeremy Kemp             detail::cl_profiling_info, name>::param_type param;
3705*6fee86a4SJeremy Kemp         cl_int result = getProfilingInfo(name, &param);
3706*6fee86a4SJeremy Kemp         if (err != nullptr) {
3707*6fee86a4SJeremy Kemp             *err = result;
3708*6fee86a4SJeremy Kemp         }
3709*6fee86a4SJeremy Kemp         return param;
3710*6fee86a4SJeremy Kemp     }
3711*6fee86a4SJeremy Kemp 
3712*6fee86a4SJeremy Kemp     /*! \brief Blocks the calling thread until this event completes.
3713*6fee86a4SJeremy Kemp      *
3714*6fee86a4SJeremy Kemp      *  Wraps clWaitForEvents().
3715*6fee86a4SJeremy Kemp      */
wait() const3716*6fee86a4SJeremy Kemp     cl_int wait() const
3717*6fee86a4SJeremy Kemp     {
3718*6fee86a4SJeremy Kemp         return detail::errHandler(
3719*6fee86a4SJeremy Kemp             ::clWaitForEvents(1, &object_),
3720*6fee86a4SJeremy Kemp             __WAIT_FOR_EVENTS_ERR);
3721*6fee86a4SJeremy Kemp     }
3722*6fee86a4SJeremy Kemp 
3723*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 110
3724*6fee86a4SJeremy Kemp     /*! \brief Registers a user callback function for a specific command execution status.
3725*6fee86a4SJeremy Kemp      *
3726*6fee86a4SJeremy Kemp      *  Wraps clSetEventCallback().
3727*6fee86a4SJeremy Kemp      */
setCallback(cl_int type,void (CL_CALLBACK * pfn_notify)(cl_event,cl_int,void *),void * user_data=nullptr)3728*6fee86a4SJeremy Kemp     cl_int setCallback(
3729*6fee86a4SJeremy Kemp         cl_int type,
3730*6fee86a4SJeremy Kemp         void (CL_CALLBACK * pfn_notify)(cl_event, cl_int, void *),
3731*6fee86a4SJeremy Kemp         void * user_data = nullptr)
3732*6fee86a4SJeremy Kemp     {
3733*6fee86a4SJeremy Kemp         return detail::errHandler(
3734*6fee86a4SJeremy Kemp             ::clSetEventCallback(
3735*6fee86a4SJeremy Kemp                 object_,
3736*6fee86a4SJeremy Kemp                 type,
3737*6fee86a4SJeremy Kemp                 pfn_notify,
3738*6fee86a4SJeremy Kemp                 user_data),
3739*6fee86a4SJeremy Kemp             __SET_EVENT_CALLBACK_ERR);
3740*6fee86a4SJeremy Kemp     }
3741*6fee86a4SJeremy Kemp #endif // CL_HPP_TARGET_OPENCL_VERSION >= 110
3742*6fee86a4SJeremy Kemp 
3743*6fee86a4SJeremy Kemp     /*! \brief Blocks the calling thread until every event specified is complete.
3744*6fee86a4SJeremy Kemp      *
3745*6fee86a4SJeremy Kemp      *  Wraps clWaitForEvents().
3746*6fee86a4SJeremy Kemp      */
3747*6fee86a4SJeremy Kemp     static cl_int
waitForEvents(const vector<Event> & events)3748*6fee86a4SJeremy Kemp     waitForEvents(const vector<Event>& events)
3749*6fee86a4SJeremy Kemp     {
3750*6fee86a4SJeremy Kemp         static_assert(sizeof(cl::Event) == sizeof(cl_event),
3751*6fee86a4SJeremy Kemp         "Size of cl::Event must be equal to size of cl_event");
3752*6fee86a4SJeremy Kemp 
3753*6fee86a4SJeremy Kemp         return detail::errHandler(
3754*6fee86a4SJeremy Kemp             ::clWaitForEvents(
3755*6fee86a4SJeremy Kemp                 (cl_uint) events.size(), (events.size() > 0) ? (cl_event*)&events.front() : nullptr),
3756*6fee86a4SJeremy Kemp             __WAIT_FOR_EVENTS_ERR);
3757*6fee86a4SJeremy Kemp     }
3758*6fee86a4SJeremy Kemp };
3759*6fee86a4SJeremy Kemp 
3760*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 110
3761*6fee86a4SJeremy Kemp /*! \brief Class interface for user events (a subset of cl_event's).
3762*6fee86a4SJeremy Kemp  *
3763*6fee86a4SJeremy Kemp  *  See Event for details about copy semantics, etc.
3764*6fee86a4SJeremy Kemp  */
3765*6fee86a4SJeremy Kemp class UserEvent : public Event
3766*6fee86a4SJeremy Kemp {
3767*6fee86a4SJeremy Kemp public:
3768*6fee86a4SJeremy Kemp     /*! \brief Constructs a user event on a given context.
3769*6fee86a4SJeremy Kemp      *
3770*6fee86a4SJeremy Kemp      *  Wraps clCreateUserEvent().
3771*6fee86a4SJeremy Kemp      */
UserEvent(const Context & context,cl_int * err=nullptr)3772*6fee86a4SJeremy Kemp     UserEvent(
3773*6fee86a4SJeremy Kemp         const Context& context,
3774*6fee86a4SJeremy Kemp         cl_int * err = nullptr)
3775*6fee86a4SJeremy Kemp     {
3776*6fee86a4SJeremy Kemp         cl_int error;
3777*6fee86a4SJeremy Kemp         object_ = ::clCreateUserEvent(
3778*6fee86a4SJeremy Kemp             context(),
3779*6fee86a4SJeremy Kemp             &error);
3780*6fee86a4SJeremy Kemp 
3781*6fee86a4SJeremy Kemp         detail::errHandler(error, __CREATE_USER_EVENT_ERR);
3782*6fee86a4SJeremy Kemp         if (err != nullptr) {
3783*6fee86a4SJeremy Kemp             *err = error;
3784*6fee86a4SJeremy Kemp         }
3785*6fee86a4SJeremy Kemp     }
3786*6fee86a4SJeremy Kemp 
3787*6fee86a4SJeremy Kemp     //! \brief Default constructor - initializes to nullptr.
UserEvent()3788*6fee86a4SJeremy Kemp     UserEvent() : Event() { }
3789*6fee86a4SJeremy Kemp 
3790*6fee86a4SJeremy Kemp     /*! \brief Sets the execution status of a user event object.
3791*6fee86a4SJeremy Kemp      *
3792*6fee86a4SJeremy Kemp      *  Wraps clSetUserEventStatus().
3793*6fee86a4SJeremy Kemp      */
setStatus(cl_int status)3794*6fee86a4SJeremy Kemp     cl_int setStatus(cl_int status)
3795*6fee86a4SJeremy Kemp     {
3796*6fee86a4SJeremy Kemp         return detail::errHandler(
3797*6fee86a4SJeremy Kemp             ::clSetUserEventStatus(object_,status),
3798*6fee86a4SJeremy Kemp             __SET_USER_EVENT_STATUS_ERR);
3799*6fee86a4SJeremy Kemp     }
3800*6fee86a4SJeremy Kemp };
3801*6fee86a4SJeremy Kemp #endif // CL_HPP_TARGET_OPENCL_VERSION >= 110
3802*6fee86a4SJeremy Kemp 
3803*6fee86a4SJeremy Kemp /*! \brief Blocks the calling thread until every event specified is complete.
3804*6fee86a4SJeremy Kemp  *
3805*6fee86a4SJeremy Kemp  *  Wraps clWaitForEvents().
3806*6fee86a4SJeremy Kemp  */
3807*6fee86a4SJeremy Kemp inline static cl_int
WaitForEvents(const vector<Event> & events)3808*6fee86a4SJeremy Kemp WaitForEvents(const vector<Event>& events)
3809*6fee86a4SJeremy Kemp {
3810*6fee86a4SJeremy Kemp     return detail::errHandler(
3811*6fee86a4SJeremy Kemp         ::clWaitForEvents(
3812*6fee86a4SJeremy Kemp             (cl_uint) events.size(), (events.size() > 0) ? (cl_event*)&events.front() : nullptr),
3813*6fee86a4SJeremy Kemp         __WAIT_FOR_EVENTS_ERR);
3814*6fee86a4SJeremy Kemp }
3815*6fee86a4SJeremy Kemp 
3816*6fee86a4SJeremy Kemp /*! \brief Class interface for cl_mem.
3817*6fee86a4SJeremy Kemp  *
3818*6fee86a4SJeremy Kemp  *  \note Copies of these objects are shallow, meaning that the copy will refer
3819*6fee86a4SJeremy Kemp  *        to the same underlying cl_mem as the original.  For details, see
3820*6fee86a4SJeremy Kemp  *        clRetainMemObject() and clReleaseMemObject().
3821*6fee86a4SJeremy Kemp  *
3822*6fee86a4SJeremy Kemp  *  \see cl_mem
3823*6fee86a4SJeremy Kemp  */
3824*6fee86a4SJeremy Kemp class Memory : public detail::Wrapper<cl_mem>
3825*6fee86a4SJeremy Kemp {
3826*6fee86a4SJeremy Kemp public:
3827*6fee86a4SJeremy Kemp     //! \brief Default constructor - initializes to nullptr.
Memory()3828*6fee86a4SJeremy Kemp     Memory() : detail::Wrapper<cl_type>() { }
3829*6fee86a4SJeremy Kemp 
3830*6fee86a4SJeremy Kemp     /*! \brief Constructor from cl_mem - takes ownership.
3831*6fee86a4SJeremy Kemp      *
3832*6fee86a4SJeremy Kemp      *  Optionally transfer ownership of a refcount on the cl_mem
3833*6fee86a4SJeremy Kemp      *  into the new Memory object.
3834*6fee86a4SJeremy Kemp      *
3835*6fee86a4SJeremy Kemp      * \param retainObject will cause the constructor to retain its cl object.
3836*6fee86a4SJeremy Kemp      *                     Defaults to false to maintain compatibility with
3837*6fee86a4SJeremy Kemp      *                     earlier versions.
3838*6fee86a4SJeremy Kemp      *
3839*6fee86a4SJeremy Kemp      *  See Memory for further details.
3840*6fee86a4SJeremy Kemp      */
Memory(const cl_mem & memory,bool retainObject)3841*6fee86a4SJeremy Kemp     explicit Memory(const cl_mem& memory, bool retainObject) :
3842*6fee86a4SJeremy Kemp         detail::Wrapper<cl_type>(memory, retainObject) { }
3843*6fee86a4SJeremy Kemp 
3844*6fee86a4SJeremy Kemp     /*! \brief Assignment operator from cl_mem - takes ownership.
3845*6fee86a4SJeremy Kemp      *
3846*6fee86a4SJeremy Kemp      *  This effectively transfers ownership of a refcount on the rhs and calls
3847*6fee86a4SJeremy Kemp      *  clReleaseMemObject() on the value previously held by this instance.
3848*6fee86a4SJeremy Kemp      */
operator =(const cl_mem & rhs)3849*6fee86a4SJeremy Kemp     Memory& operator = (const cl_mem& rhs)
3850*6fee86a4SJeremy Kemp     {
3851*6fee86a4SJeremy Kemp         detail::Wrapper<cl_type>::operator=(rhs);
3852*6fee86a4SJeremy Kemp         return *this;
3853*6fee86a4SJeremy Kemp     }
3854*6fee86a4SJeremy Kemp 
3855*6fee86a4SJeremy Kemp     //! \brief Wrapper for clGetMemObjectInfo().
3856*6fee86a4SJeremy Kemp     template <typename T>
getInfo(cl_mem_info name,T * param) const3857*6fee86a4SJeremy Kemp     cl_int getInfo(cl_mem_info name, T* param) const
3858*6fee86a4SJeremy Kemp     {
3859*6fee86a4SJeremy Kemp         return detail::errHandler(
3860*6fee86a4SJeremy Kemp             detail::getInfo(&::clGetMemObjectInfo, object_, name, param),
3861*6fee86a4SJeremy Kemp             __GET_MEM_OBJECT_INFO_ERR);
3862*6fee86a4SJeremy Kemp     }
3863*6fee86a4SJeremy Kemp 
3864*6fee86a4SJeremy Kemp     //! \brief Wrapper for clGetMemObjectInfo() that returns by value.
3865*6fee86a4SJeremy Kemp     template <cl_mem_info name> typename
3866*6fee86a4SJeremy Kemp     detail::param_traits<detail::cl_mem_info, name>::param_type
getInfo(cl_int * err=nullptr) const3867*6fee86a4SJeremy Kemp     getInfo(cl_int* err = nullptr) const
3868*6fee86a4SJeremy Kemp     {
3869*6fee86a4SJeremy Kemp         typename detail::param_traits<
3870*6fee86a4SJeremy Kemp             detail::cl_mem_info, name>::param_type param;
3871*6fee86a4SJeremy Kemp         cl_int result = getInfo(name, &param);
3872*6fee86a4SJeremy Kemp         if (err != nullptr) {
3873*6fee86a4SJeremy Kemp             *err = result;
3874*6fee86a4SJeremy Kemp         }
3875*6fee86a4SJeremy Kemp         return param;
3876*6fee86a4SJeremy Kemp     }
3877*6fee86a4SJeremy Kemp 
3878*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 110
3879*6fee86a4SJeremy Kemp     /*! \brief Registers a callback function to be called when the memory object
3880*6fee86a4SJeremy Kemp      *         is no longer needed.
3881*6fee86a4SJeremy Kemp      *
3882*6fee86a4SJeremy Kemp      *  Wraps clSetMemObjectDestructorCallback().
3883*6fee86a4SJeremy Kemp      *
3884*6fee86a4SJeremy Kemp      *  Repeated calls to this function, for a given cl_mem value, will append
3885*6fee86a4SJeremy Kemp      *  to the list of functions called (in reverse order) when memory object's
3886*6fee86a4SJeremy Kemp      *  resources are freed and the memory object is deleted.
3887*6fee86a4SJeremy Kemp      *
3888*6fee86a4SJeremy Kemp      *  \note
3889*6fee86a4SJeremy Kemp      *  The registered callbacks are associated with the underlying cl_mem
3890*6fee86a4SJeremy Kemp      *  value - not the Memory class instance.
3891*6fee86a4SJeremy Kemp      */
setDestructorCallback(void (CL_CALLBACK * pfn_notify)(cl_mem,void *),void * user_data=nullptr)3892*6fee86a4SJeremy Kemp     cl_int setDestructorCallback(
3893*6fee86a4SJeremy Kemp         void (CL_CALLBACK * pfn_notify)(cl_mem, void *),
3894*6fee86a4SJeremy Kemp         void * user_data = nullptr)
3895*6fee86a4SJeremy Kemp     {
3896*6fee86a4SJeremy Kemp         return detail::errHandler(
3897*6fee86a4SJeremy Kemp             ::clSetMemObjectDestructorCallback(
3898*6fee86a4SJeremy Kemp                 object_,
3899*6fee86a4SJeremy Kemp                 pfn_notify,
3900*6fee86a4SJeremy Kemp                 user_data),
3901*6fee86a4SJeremy Kemp             __SET_MEM_OBJECT_DESTRUCTOR_CALLBACK_ERR);
3902*6fee86a4SJeremy Kemp     }
3903*6fee86a4SJeremy Kemp #endif // CL_HPP_TARGET_OPENCL_VERSION >= 110
3904*6fee86a4SJeremy Kemp 
3905*6fee86a4SJeremy Kemp };
3906*6fee86a4SJeremy Kemp 
3907*6fee86a4SJeremy Kemp // Pre-declare copy functions
3908*6fee86a4SJeremy Kemp class Buffer;
3909*6fee86a4SJeremy Kemp template< typename IteratorType >
3910*6fee86a4SJeremy Kemp cl_int copy( IteratorType startIterator, IteratorType endIterator, cl::Buffer &buffer );
3911*6fee86a4SJeremy Kemp template< typename IteratorType >
3912*6fee86a4SJeremy Kemp cl_int copy( const cl::Buffer &buffer, IteratorType startIterator, IteratorType endIterator );
3913*6fee86a4SJeremy Kemp template< typename IteratorType >
3914*6fee86a4SJeremy Kemp cl_int copy( const CommandQueue &queue, IteratorType startIterator, IteratorType endIterator, cl::Buffer &buffer );
3915*6fee86a4SJeremy Kemp template< typename IteratorType >
3916*6fee86a4SJeremy Kemp cl_int copy( const CommandQueue &queue, const cl::Buffer &buffer, IteratorType startIterator, IteratorType endIterator );
3917*6fee86a4SJeremy Kemp 
3918*6fee86a4SJeremy Kemp 
3919*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 200
3920*6fee86a4SJeremy Kemp namespace detail
3921*6fee86a4SJeremy Kemp {
3922*6fee86a4SJeremy Kemp     class SVMTraitNull
3923*6fee86a4SJeremy Kemp     {
3924*6fee86a4SJeremy Kemp     public:
getSVMMemFlags()3925*6fee86a4SJeremy Kemp         static cl_svm_mem_flags getSVMMemFlags()
3926*6fee86a4SJeremy Kemp         {
3927*6fee86a4SJeremy Kemp             return 0;
3928*6fee86a4SJeremy Kemp         }
3929*6fee86a4SJeremy Kemp     };
3930*6fee86a4SJeremy Kemp } // namespace detail
3931*6fee86a4SJeremy Kemp 
3932*6fee86a4SJeremy Kemp template<class Trait = detail::SVMTraitNull>
3933*6fee86a4SJeremy Kemp class SVMTraitReadWrite
3934*6fee86a4SJeremy Kemp {
3935*6fee86a4SJeremy Kemp public:
getSVMMemFlags()3936*6fee86a4SJeremy Kemp     static cl_svm_mem_flags getSVMMemFlags()
3937*6fee86a4SJeremy Kemp     {
3938*6fee86a4SJeremy Kemp         return CL_MEM_READ_WRITE |
3939*6fee86a4SJeremy Kemp             Trait::getSVMMemFlags();
3940*6fee86a4SJeremy Kemp     }
3941*6fee86a4SJeremy Kemp };
3942*6fee86a4SJeremy Kemp 
3943*6fee86a4SJeremy Kemp template<class Trait = detail::SVMTraitNull>
3944*6fee86a4SJeremy Kemp class SVMTraitReadOnly
3945*6fee86a4SJeremy Kemp {
3946*6fee86a4SJeremy Kemp public:
getSVMMemFlags()3947*6fee86a4SJeremy Kemp     static cl_svm_mem_flags getSVMMemFlags()
3948*6fee86a4SJeremy Kemp     {
3949*6fee86a4SJeremy Kemp         return CL_MEM_READ_ONLY |
3950*6fee86a4SJeremy Kemp             Trait::getSVMMemFlags();
3951*6fee86a4SJeremy Kemp     }
3952*6fee86a4SJeremy Kemp };
3953*6fee86a4SJeremy Kemp 
3954*6fee86a4SJeremy Kemp template<class Trait = detail::SVMTraitNull>
3955*6fee86a4SJeremy Kemp class SVMTraitWriteOnly
3956*6fee86a4SJeremy Kemp {
3957*6fee86a4SJeremy Kemp public:
getSVMMemFlags()3958*6fee86a4SJeremy Kemp     static cl_svm_mem_flags getSVMMemFlags()
3959*6fee86a4SJeremy Kemp     {
3960*6fee86a4SJeremy Kemp         return CL_MEM_WRITE_ONLY |
3961*6fee86a4SJeremy Kemp             Trait::getSVMMemFlags();
3962*6fee86a4SJeremy Kemp     }
3963*6fee86a4SJeremy Kemp };
3964*6fee86a4SJeremy Kemp 
3965*6fee86a4SJeremy Kemp template<class Trait = SVMTraitReadWrite<>>
3966*6fee86a4SJeremy Kemp class SVMTraitCoarse
3967*6fee86a4SJeremy Kemp {
3968*6fee86a4SJeremy Kemp public:
getSVMMemFlags()3969*6fee86a4SJeremy Kemp     static cl_svm_mem_flags getSVMMemFlags()
3970*6fee86a4SJeremy Kemp     {
3971*6fee86a4SJeremy Kemp         return Trait::getSVMMemFlags();
3972*6fee86a4SJeremy Kemp     }
3973*6fee86a4SJeremy Kemp };
3974*6fee86a4SJeremy Kemp 
3975*6fee86a4SJeremy Kemp template<class Trait = SVMTraitReadWrite<>>
3976*6fee86a4SJeremy Kemp class SVMTraitFine
3977*6fee86a4SJeremy Kemp {
3978*6fee86a4SJeremy Kemp public:
getSVMMemFlags()3979*6fee86a4SJeremy Kemp     static cl_svm_mem_flags getSVMMemFlags()
3980*6fee86a4SJeremy Kemp     {
3981*6fee86a4SJeremy Kemp         return CL_MEM_SVM_FINE_GRAIN_BUFFER |
3982*6fee86a4SJeremy Kemp             Trait::getSVMMemFlags();
3983*6fee86a4SJeremy Kemp     }
3984*6fee86a4SJeremy Kemp };
3985*6fee86a4SJeremy Kemp 
3986*6fee86a4SJeremy Kemp template<class Trait = SVMTraitReadWrite<>>
3987*6fee86a4SJeremy Kemp class SVMTraitAtomic
3988*6fee86a4SJeremy Kemp {
3989*6fee86a4SJeremy Kemp public:
getSVMMemFlags()3990*6fee86a4SJeremy Kemp     static cl_svm_mem_flags getSVMMemFlags()
3991*6fee86a4SJeremy Kemp     {
3992*6fee86a4SJeremy Kemp         return
3993*6fee86a4SJeremy Kemp             CL_MEM_SVM_FINE_GRAIN_BUFFER |
3994*6fee86a4SJeremy Kemp             CL_MEM_SVM_ATOMICS |
3995*6fee86a4SJeremy Kemp             Trait::getSVMMemFlags();
3996*6fee86a4SJeremy Kemp     }
3997*6fee86a4SJeremy Kemp };
3998*6fee86a4SJeremy Kemp 
3999*6fee86a4SJeremy Kemp // Pre-declare SVM map function
4000*6fee86a4SJeremy Kemp template<typename T>
4001*6fee86a4SJeremy Kemp inline cl_int enqueueMapSVM(
4002*6fee86a4SJeremy Kemp     T* ptr,
4003*6fee86a4SJeremy Kemp     cl_bool blocking,
4004*6fee86a4SJeremy Kemp     cl_map_flags flags,
4005*6fee86a4SJeremy Kemp     size_type size,
4006*6fee86a4SJeremy Kemp     const vector<Event>* events = nullptr,
4007*6fee86a4SJeremy Kemp     Event* event = nullptr);
4008*6fee86a4SJeremy Kemp 
4009*6fee86a4SJeremy Kemp /**
4010*6fee86a4SJeremy Kemp  * STL-like allocator class for managing SVM objects provided for convenience.
4011*6fee86a4SJeremy Kemp  *
4012*6fee86a4SJeremy Kemp  * Note that while this behaves like an allocator for the purposes of constructing vectors and similar objects,
4013*6fee86a4SJeremy Kemp  * care must be taken when using with smart pointers.
4014*6fee86a4SJeremy Kemp  * The allocator should not be used to construct a unique_ptr if we are using coarse-grained SVM mode because
4015*6fee86a4SJeremy Kemp  * the coarse-grained management behaviour would behave incorrectly with respect to reference counting.
4016*6fee86a4SJeremy Kemp  *
4017*6fee86a4SJeremy Kemp  * Instead the allocator embeds a Deleter which may be used with unique_ptr and is used
4018*6fee86a4SJeremy Kemp  * with the allocate_shared and allocate_ptr supplied operations.
4019*6fee86a4SJeremy Kemp  */
4020*6fee86a4SJeremy Kemp template<typename T, class SVMTrait>
4021*6fee86a4SJeremy Kemp class SVMAllocator {
4022*6fee86a4SJeremy Kemp private:
4023*6fee86a4SJeremy Kemp     Context context_;
4024*6fee86a4SJeremy Kemp 
4025*6fee86a4SJeremy Kemp public:
4026*6fee86a4SJeremy Kemp     typedef T value_type;
4027*6fee86a4SJeremy Kemp     typedef value_type* pointer;
4028*6fee86a4SJeremy Kemp     typedef const value_type* const_pointer;
4029*6fee86a4SJeremy Kemp     typedef value_type& reference;
4030*6fee86a4SJeremy Kemp     typedef const value_type& const_reference;
4031*6fee86a4SJeremy Kemp     typedef std::size_t size_type;
4032*6fee86a4SJeremy Kemp     typedef std::ptrdiff_t difference_type;
4033*6fee86a4SJeremy Kemp 
4034*6fee86a4SJeremy Kemp     template<typename U>
4035*6fee86a4SJeremy Kemp     struct rebind
4036*6fee86a4SJeremy Kemp     {
4037*6fee86a4SJeremy Kemp         typedef SVMAllocator<U, SVMTrait> other;
4038*6fee86a4SJeremy Kemp     };
4039*6fee86a4SJeremy Kemp 
4040*6fee86a4SJeremy Kemp     template<typename U, typename V>
4041*6fee86a4SJeremy Kemp     friend class SVMAllocator;
4042*6fee86a4SJeremy Kemp 
SVMAllocator()4043*6fee86a4SJeremy Kemp     SVMAllocator() :
4044*6fee86a4SJeremy Kemp         context_(Context::getDefault())
4045*6fee86a4SJeremy Kemp     {
4046*6fee86a4SJeremy Kemp     }
4047*6fee86a4SJeremy Kemp 
SVMAllocator(cl::Context context)4048*6fee86a4SJeremy Kemp     explicit SVMAllocator(cl::Context context) :
4049*6fee86a4SJeremy Kemp         context_(context)
4050*6fee86a4SJeremy Kemp     {
4051*6fee86a4SJeremy Kemp     }
4052*6fee86a4SJeremy Kemp 
4053*6fee86a4SJeremy Kemp 
SVMAllocator(const SVMAllocator & other)4054*6fee86a4SJeremy Kemp     SVMAllocator(const SVMAllocator &other) :
4055*6fee86a4SJeremy Kemp         context_(other.context_)
4056*6fee86a4SJeremy Kemp     {
4057*6fee86a4SJeremy Kemp     }
4058*6fee86a4SJeremy Kemp 
4059*6fee86a4SJeremy Kemp     template<typename U>
SVMAllocator(const SVMAllocator<U,SVMTrait> & other)4060*6fee86a4SJeremy Kemp     SVMAllocator(const SVMAllocator<U, SVMTrait> &other) :
4061*6fee86a4SJeremy Kemp         context_(other.context_)
4062*6fee86a4SJeremy Kemp     {
4063*6fee86a4SJeremy Kemp     }
4064*6fee86a4SJeremy Kemp 
~SVMAllocator()4065*6fee86a4SJeremy Kemp     ~SVMAllocator()
4066*6fee86a4SJeremy Kemp     {
4067*6fee86a4SJeremy Kemp     }
4068*6fee86a4SJeremy Kemp 
address(reference r)4069*6fee86a4SJeremy Kemp     pointer address(reference r) noexcept
4070*6fee86a4SJeremy Kemp     {
4071*6fee86a4SJeremy Kemp         return std::addressof(r);
4072*6fee86a4SJeremy Kemp     }
4073*6fee86a4SJeremy Kemp 
address(const_reference r)4074*6fee86a4SJeremy Kemp     const_pointer address(const_reference r) noexcept
4075*6fee86a4SJeremy Kemp     {
4076*6fee86a4SJeremy Kemp         return std::addressof(r);
4077*6fee86a4SJeremy Kemp     }
4078*6fee86a4SJeremy Kemp 
4079*6fee86a4SJeremy Kemp     /**
4080*6fee86a4SJeremy Kemp      * Allocate an SVM pointer.
4081*6fee86a4SJeremy Kemp      *
4082*6fee86a4SJeremy Kemp      * If the allocator is coarse-grained, this will take ownership to allow
4083*6fee86a4SJeremy Kemp      * containers to correctly construct data in place.
4084*6fee86a4SJeremy Kemp      */
allocate(size_type size,typename cl::SVMAllocator<void,SVMTrait>::const_pointer=0,bool map=true)4085*6fee86a4SJeremy Kemp     pointer allocate(
4086*6fee86a4SJeremy Kemp         size_type size,
4087*6fee86a4SJeremy Kemp         typename cl::SVMAllocator<void, SVMTrait>::const_pointer = 0,
4088*6fee86a4SJeremy Kemp         bool map = true)
4089*6fee86a4SJeremy Kemp     {
4090*6fee86a4SJeremy Kemp         // Allocate memory with default alignment matching the size of the type
4091*6fee86a4SJeremy Kemp         void* voidPointer =
4092*6fee86a4SJeremy Kemp             clSVMAlloc(
4093*6fee86a4SJeremy Kemp             context_(),
4094*6fee86a4SJeremy Kemp             SVMTrait::getSVMMemFlags(),
4095*6fee86a4SJeremy Kemp             size*sizeof(T),
4096*6fee86a4SJeremy Kemp             0);
4097*6fee86a4SJeremy Kemp         pointer retValue = reinterpret_cast<pointer>(
4098*6fee86a4SJeremy Kemp             voidPointer);
4099*6fee86a4SJeremy Kemp #if defined(CL_HPP_ENABLE_EXCEPTIONS)
4100*6fee86a4SJeremy Kemp         if (!retValue) {
4101*6fee86a4SJeremy Kemp             std::bad_alloc excep;
4102*6fee86a4SJeremy Kemp             throw excep;
4103*6fee86a4SJeremy Kemp         }
4104*6fee86a4SJeremy Kemp #endif // #if defined(CL_HPP_ENABLE_EXCEPTIONS)
4105*6fee86a4SJeremy Kemp 
4106*6fee86a4SJeremy Kemp         // If allocation was coarse-grained then map it
4107*6fee86a4SJeremy Kemp         if (map && !(SVMTrait::getSVMMemFlags() & CL_MEM_SVM_FINE_GRAIN_BUFFER)) {
4108*6fee86a4SJeremy Kemp             cl_int err = enqueueMapSVM(retValue, CL_TRUE, CL_MAP_READ | CL_MAP_WRITE, size*sizeof(T));
4109*6fee86a4SJeremy Kemp             if (err != CL_SUCCESS) {
4110*6fee86a4SJeremy Kemp                 clSVMFree(context_(), retValue);
4111*6fee86a4SJeremy Kemp                 retValue = nullptr;
4112*6fee86a4SJeremy Kemp #if defined(CL_HPP_ENABLE_EXCEPTIONS)
4113*6fee86a4SJeremy Kemp                 std::bad_alloc excep;
4114*6fee86a4SJeremy Kemp                 throw excep;
4115*6fee86a4SJeremy Kemp #endif
4116*6fee86a4SJeremy Kemp             }
4117*6fee86a4SJeremy Kemp         }
4118*6fee86a4SJeremy Kemp 
4119*6fee86a4SJeremy Kemp         // If exceptions disabled, return null pointer from allocator
4120*6fee86a4SJeremy Kemp         return retValue;
4121*6fee86a4SJeremy Kemp     }
4122*6fee86a4SJeremy Kemp 
deallocate(pointer p,size_type)4123*6fee86a4SJeremy Kemp     void deallocate(pointer p, size_type)
4124*6fee86a4SJeremy Kemp     {
4125*6fee86a4SJeremy Kemp         clSVMFree(context_(), p);
4126*6fee86a4SJeremy Kemp     }
4127*6fee86a4SJeremy Kemp 
4128*6fee86a4SJeremy Kemp     /**
4129*6fee86a4SJeremy Kemp      * Return the maximum possible allocation size.
4130*6fee86a4SJeremy Kemp      * This is the minimum of the maximum sizes of all devices in the context.
4131*6fee86a4SJeremy Kemp      */
max_size() const4132*6fee86a4SJeremy Kemp     size_type max_size() const noexcept
4133*6fee86a4SJeremy Kemp     {
4134*6fee86a4SJeremy Kemp         size_type maxSize = std::numeric_limits<size_type>::max() / sizeof(T);
4135*6fee86a4SJeremy Kemp 
4136*6fee86a4SJeremy Kemp         for (const Device &d : context_.getInfo<CL_CONTEXT_DEVICES>()) {
4137*6fee86a4SJeremy Kemp             maxSize = std::min(
4138*6fee86a4SJeremy Kemp                 maxSize,
4139*6fee86a4SJeremy Kemp                 static_cast<size_type>(d.getInfo<CL_DEVICE_MAX_MEM_ALLOC_SIZE>()));
4140*6fee86a4SJeremy Kemp         }
4141*6fee86a4SJeremy Kemp 
4142*6fee86a4SJeremy Kemp         return maxSize;
4143*6fee86a4SJeremy Kemp     }
4144*6fee86a4SJeremy Kemp 
4145*6fee86a4SJeremy Kemp     template< class U, class... Args >
construct(U * p,Args &&...args)4146*6fee86a4SJeremy Kemp     void construct(U* p, Args&&... args)
4147*6fee86a4SJeremy Kemp     {
4148*6fee86a4SJeremy Kemp         new(p)T(args...);
4149*6fee86a4SJeremy Kemp     }
4150*6fee86a4SJeremy Kemp 
4151*6fee86a4SJeremy Kemp     template< class U >
destroy(U * p)4152*6fee86a4SJeremy Kemp     void destroy(U* p)
4153*6fee86a4SJeremy Kemp     {
4154*6fee86a4SJeremy Kemp         p->~U();
4155*6fee86a4SJeremy Kemp     }
4156*6fee86a4SJeremy Kemp 
4157*6fee86a4SJeremy Kemp     /**
4158*6fee86a4SJeremy Kemp      * Returns true if the contexts match.
4159*6fee86a4SJeremy Kemp      */
operator ==(SVMAllocator const & rhs)4160*6fee86a4SJeremy Kemp     inline bool operator==(SVMAllocator const& rhs)
4161*6fee86a4SJeremy Kemp     {
4162*6fee86a4SJeremy Kemp         return (context_==rhs.context_);
4163*6fee86a4SJeremy Kemp     }
4164*6fee86a4SJeremy Kemp 
operator !=(SVMAllocator const & a)4165*6fee86a4SJeremy Kemp     inline bool operator!=(SVMAllocator const& a)
4166*6fee86a4SJeremy Kemp     {
4167*6fee86a4SJeremy Kemp         return !operator==(a);
4168*6fee86a4SJeremy Kemp     }
4169*6fee86a4SJeremy Kemp }; // class SVMAllocator        return cl::pointer<T>(tmp, detail::Deleter<T, Alloc>{alloc, copies});
4170*6fee86a4SJeremy Kemp 
4171*6fee86a4SJeremy Kemp 
4172*6fee86a4SJeremy Kemp template<class SVMTrait>
4173*6fee86a4SJeremy Kemp class SVMAllocator<void, SVMTrait> {
4174*6fee86a4SJeremy Kemp public:
4175*6fee86a4SJeremy Kemp     typedef void value_type;
4176*6fee86a4SJeremy Kemp     typedef value_type* pointer;
4177*6fee86a4SJeremy Kemp     typedef const value_type* const_pointer;
4178*6fee86a4SJeremy Kemp 
4179*6fee86a4SJeremy Kemp     template<typename U>
4180*6fee86a4SJeremy Kemp     struct rebind
4181*6fee86a4SJeremy Kemp     {
4182*6fee86a4SJeremy Kemp         typedef SVMAllocator<U, SVMTrait> other;
4183*6fee86a4SJeremy Kemp     };
4184*6fee86a4SJeremy Kemp 
4185*6fee86a4SJeremy Kemp     template<typename U, typename V>
4186*6fee86a4SJeremy Kemp     friend class SVMAllocator;
4187*6fee86a4SJeremy Kemp };
4188*6fee86a4SJeremy Kemp 
4189*6fee86a4SJeremy Kemp #if !defined(CL_HPP_NO_STD_UNIQUE_PTR)
4190*6fee86a4SJeremy Kemp namespace detail
4191*6fee86a4SJeremy Kemp {
4192*6fee86a4SJeremy Kemp     template<class Alloc>
4193*6fee86a4SJeremy Kemp     class Deleter {
4194*6fee86a4SJeremy Kemp     private:
4195*6fee86a4SJeremy Kemp         Alloc alloc_;
4196*6fee86a4SJeremy Kemp         size_type copies_;
4197*6fee86a4SJeremy Kemp 
4198*6fee86a4SJeremy Kemp     public:
4199*6fee86a4SJeremy Kemp         typedef typename std::allocator_traits<Alloc>::pointer pointer;
4200*6fee86a4SJeremy Kemp 
Deleter(const Alloc & alloc,size_type copies)4201*6fee86a4SJeremy Kemp         Deleter(const Alloc &alloc, size_type copies) : alloc_{ alloc }, copies_{ copies }
4202*6fee86a4SJeremy Kemp         {
4203*6fee86a4SJeremy Kemp         }
4204*6fee86a4SJeremy Kemp 
operator ()(pointer ptr) const4205*6fee86a4SJeremy Kemp         void operator()(pointer ptr) const {
4206*6fee86a4SJeremy Kemp             Alloc tmpAlloc{ alloc_ };
4207*6fee86a4SJeremy Kemp             std::allocator_traits<Alloc>::destroy(tmpAlloc, std::addressof(*ptr));
4208*6fee86a4SJeremy Kemp             std::allocator_traits<Alloc>::deallocate(tmpAlloc, ptr, copies_);
4209*6fee86a4SJeremy Kemp         }
4210*6fee86a4SJeremy Kemp     };
4211*6fee86a4SJeremy Kemp } // namespace detail
4212*6fee86a4SJeremy Kemp 
4213*6fee86a4SJeremy Kemp /**
4214*6fee86a4SJeremy Kemp  * Allocation operation compatible with std::allocate_ptr.
4215*6fee86a4SJeremy Kemp  * Creates a unique_ptr<T> by default.
4216*6fee86a4SJeremy Kemp  * This requirement is to ensure that the control block is not
4217*6fee86a4SJeremy Kemp  * allocated in memory inaccessible to the host.
4218*6fee86a4SJeremy Kemp  */
4219*6fee86a4SJeremy Kemp template <class T, class Alloc, class... Args>
allocate_pointer(const Alloc & alloc_,Args &&...args)4220*6fee86a4SJeremy Kemp cl::pointer<T, detail::Deleter<Alloc>> allocate_pointer(const Alloc &alloc_, Args&&... args)
4221*6fee86a4SJeremy Kemp {
4222*6fee86a4SJeremy Kemp     Alloc alloc(alloc_);
4223*6fee86a4SJeremy Kemp     static const size_type copies = 1;
4224*6fee86a4SJeremy Kemp 
4225*6fee86a4SJeremy Kemp     // Ensure that creation of the management block and the
4226*6fee86a4SJeremy Kemp     // object are dealt with separately such that we only provide a deleter
4227*6fee86a4SJeremy Kemp 
4228*6fee86a4SJeremy Kemp     T* tmp = std::allocator_traits<Alloc>::allocate(alloc, copies);
4229*6fee86a4SJeremy Kemp     if (!tmp) {
4230*6fee86a4SJeremy Kemp         std::bad_alloc excep;
4231*6fee86a4SJeremy Kemp         throw excep;
4232*6fee86a4SJeremy Kemp     }
4233*6fee86a4SJeremy Kemp     try {
4234*6fee86a4SJeremy Kemp         std::allocator_traits<Alloc>::construct(
4235*6fee86a4SJeremy Kemp             alloc,
4236*6fee86a4SJeremy Kemp             std::addressof(*tmp),
4237*6fee86a4SJeremy Kemp             std::forward<Args>(args)...);
4238*6fee86a4SJeremy Kemp 
4239*6fee86a4SJeremy Kemp         return cl::pointer<T, detail::Deleter<Alloc>>(tmp, detail::Deleter<Alloc>{alloc, copies});
4240*6fee86a4SJeremy Kemp     }
4241*6fee86a4SJeremy Kemp     catch (std::bad_alloc&)
4242*6fee86a4SJeremy Kemp     {
4243*6fee86a4SJeremy Kemp         std::allocator_traits<Alloc>::deallocate(alloc, tmp, copies);
4244*6fee86a4SJeremy Kemp         throw;
4245*6fee86a4SJeremy Kemp     }
4246*6fee86a4SJeremy Kemp }
4247*6fee86a4SJeremy Kemp 
4248*6fee86a4SJeremy Kemp template< class T, class SVMTrait, class... Args >
allocate_svm(Args...args)4249*6fee86a4SJeremy Kemp cl::pointer<T, detail::Deleter<SVMAllocator<T, SVMTrait>>> allocate_svm(Args... args)
4250*6fee86a4SJeremy Kemp {
4251*6fee86a4SJeremy Kemp     SVMAllocator<T, SVMTrait> alloc;
4252*6fee86a4SJeremy Kemp     return cl::allocate_pointer<T>(alloc, args...);
4253*6fee86a4SJeremy Kemp }
4254*6fee86a4SJeremy Kemp 
4255*6fee86a4SJeremy Kemp template< class T, class SVMTrait, class... Args >
allocate_svm(const cl::Context & c,Args...args)4256*6fee86a4SJeremy Kemp cl::pointer<T, detail::Deleter<SVMAllocator<T, SVMTrait>>> allocate_svm(const cl::Context &c, Args... args)
4257*6fee86a4SJeremy Kemp {
4258*6fee86a4SJeremy Kemp     SVMAllocator<T, SVMTrait> alloc(c);
4259*6fee86a4SJeremy Kemp     return cl::allocate_pointer<T>(alloc, args...);
4260*6fee86a4SJeremy Kemp }
4261*6fee86a4SJeremy Kemp #endif // #if !defined(CL_HPP_NO_STD_UNIQUE_PTR)
4262*6fee86a4SJeremy Kemp 
4263*6fee86a4SJeremy Kemp /*! \brief Vector alias to simplify contruction of coarse-grained SVM containers.
4264*6fee86a4SJeremy Kemp  *
4265*6fee86a4SJeremy Kemp  */
4266*6fee86a4SJeremy Kemp template < class T >
4267*6fee86a4SJeremy Kemp using coarse_svm_vector = vector<T, cl::SVMAllocator<int, cl::SVMTraitCoarse<>>>;
4268*6fee86a4SJeremy Kemp 
4269*6fee86a4SJeremy Kemp /*! \brief Vector alias to simplify contruction of fine-grained SVM containers.
4270*6fee86a4SJeremy Kemp *
4271*6fee86a4SJeremy Kemp */
4272*6fee86a4SJeremy Kemp template < class T >
4273*6fee86a4SJeremy Kemp using fine_svm_vector = vector<T, cl::SVMAllocator<int, cl::SVMTraitFine<>>>;
4274*6fee86a4SJeremy Kemp 
4275*6fee86a4SJeremy Kemp /*! \brief Vector alias to simplify contruction of fine-grained SVM containers that support platform atomics.
4276*6fee86a4SJeremy Kemp *
4277*6fee86a4SJeremy Kemp */
4278*6fee86a4SJeremy Kemp template < class T >
4279*6fee86a4SJeremy Kemp using atomic_svm_vector = vector<T, cl::SVMAllocator<int, cl::SVMTraitAtomic<>>>;
4280*6fee86a4SJeremy Kemp 
4281*6fee86a4SJeremy Kemp #endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 200
4282*6fee86a4SJeremy Kemp 
4283*6fee86a4SJeremy Kemp 
4284*6fee86a4SJeremy Kemp /*! \brief Class interface for Buffer Memory Objects.
4285*6fee86a4SJeremy Kemp  *
4286*6fee86a4SJeremy Kemp  *  See Memory for details about copy semantics, etc.
4287*6fee86a4SJeremy Kemp  *
4288*6fee86a4SJeremy Kemp  *  \see Memory
4289*6fee86a4SJeremy Kemp  */
4290*6fee86a4SJeremy Kemp class Buffer : public Memory
4291*6fee86a4SJeremy Kemp {
4292*6fee86a4SJeremy Kemp public:
4293*6fee86a4SJeremy Kemp 
4294*6fee86a4SJeremy Kemp     /*! \brief Constructs a Buffer in a specified context.
4295*6fee86a4SJeremy Kemp      *
4296*6fee86a4SJeremy Kemp      *  Wraps clCreateBuffer().
4297*6fee86a4SJeremy Kemp      *
4298*6fee86a4SJeremy Kemp      *  \param host_ptr Storage to be used if the CL_MEM_USE_HOST_PTR flag was
4299*6fee86a4SJeremy Kemp      *                  specified.  Note alignment & exclusivity requirements.
4300*6fee86a4SJeremy Kemp      */
Buffer(const Context & context,cl_mem_flags flags,size_type size,void * host_ptr=nullptr,cl_int * err=nullptr)4301*6fee86a4SJeremy Kemp     Buffer(
4302*6fee86a4SJeremy Kemp         const Context& context,
4303*6fee86a4SJeremy Kemp         cl_mem_flags flags,
4304*6fee86a4SJeremy Kemp         size_type size,
4305*6fee86a4SJeremy Kemp         void* host_ptr = nullptr,
4306*6fee86a4SJeremy Kemp         cl_int* err = nullptr)
4307*6fee86a4SJeremy Kemp     {
4308*6fee86a4SJeremy Kemp         cl_int error;
4309*6fee86a4SJeremy Kemp         object_ = ::clCreateBuffer(context(), flags, size, host_ptr, &error);
4310*6fee86a4SJeremy Kemp 
4311*6fee86a4SJeremy Kemp         detail::errHandler(error, __CREATE_BUFFER_ERR);
4312*6fee86a4SJeremy Kemp         if (err != nullptr) {
4313*6fee86a4SJeremy Kemp             *err = error;
4314*6fee86a4SJeremy Kemp         }
4315*6fee86a4SJeremy Kemp     }
4316*6fee86a4SJeremy Kemp 
4317*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 300
4318*6fee86a4SJeremy Kemp     /*! \brief Constructs a Buffer in a specified context and with specified properties.
4319*6fee86a4SJeremy Kemp      *
4320*6fee86a4SJeremy Kemp      *  Wraps clCreateBufferWithProperties().
4321*6fee86a4SJeremy Kemp      *
4322*6fee86a4SJeremy Kemp      *  \param properties Optional list of properties for the buffer object and
4323*6fee86a4SJeremy Kemp      *                    their corresponding values. The non-empty list must
4324*6fee86a4SJeremy Kemp      *                    end with 0.
4325*6fee86a4SJeremy Kemp      *  \param host_ptr Storage to be used if the CL_MEM_USE_HOST_PTR flag was
4326*6fee86a4SJeremy Kemp      *                  specified. Note alignment & exclusivity requirements.
4327*6fee86a4SJeremy Kemp      */
Buffer(const Context & context,const vector<cl_mem_properties> & properties,cl_mem_flags flags,size_type size,void * host_ptr=nullptr,cl_int * err=nullptr)4328*6fee86a4SJeremy Kemp     Buffer(
4329*6fee86a4SJeremy Kemp         const Context& context,
4330*6fee86a4SJeremy Kemp         const vector<cl_mem_properties>& properties,
4331*6fee86a4SJeremy Kemp         cl_mem_flags flags,
4332*6fee86a4SJeremy Kemp         size_type size,
4333*6fee86a4SJeremy Kemp         void* host_ptr = nullptr,
4334*6fee86a4SJeremy Kemp         cl_int* err = nullptr)
4335*6fee86a4SJeremy Kemp     {
4336*6fee86a4SJeremy Kemp         cl_int error;
4337*6fee86a4SJeremy Kemp 
4338*6fee86a4SJeremy Kemp         if (properties.empty()) {
4339*6fee86a4SJeremy Kemp             object_ = ::clCreateBufferWithProperties(context(), nullptr, flags,
4340*6fee86a4SJeremy Kemp                                                      size, host_ptr, &error);
4341*6fee86a4SJeremy Kemp         }
4342*6fee86a4SJeremy Kemp         else {
4343*6fee86a4SJeremy Kemp             object_ = ::clCreateBufferWithProperties(
4344*6fee86a4SJeremy Kemp                 context(), properties.data(), flags, size, host_ptr, &error);
4345*6fee86a4SJeremy Kemp         }
4346*6fee86a4SJeremy Kemp 
4347*6fee86a4SJeremy Kemp         detail::errHandler(error, __CREATE_BUFFER_ERR);
4348*6fee86a4SJeremy Kemp         if (err != nullptr) {
4349*6fee86a4SJeremy Kemp             *err = error;
4350*6fee86a4SJeremy Kemp         }
4351*6fee86a4SJeremy Kemp     }
4352*6fee86a4SJeremy Kemp #endif
4353*6fee86a4SJeremy Kemp 
4354*6fee86a4SJeremy Kemp     /*! \brief Constructs a Buffer in the default context.
4355*6fee86a4SJeremy Kemp      *
4356*6fee86a4SJeremy Kemp      *  Wraps clCreateBuffer().
4357*6fee86a4SJeremy Kemp      *
4358*6fee86a4SJeremy Kemp      *  \param host_ptr Storage to be used if the CL_MEM_USE_HOST_PTR flag was
4359*6fee86a4SJeremy Kemp      *                  specified.  Note alignment & exclusivity requirements.
4360*6fee86a4SJeremy Kemp      *
4361*6fee86a4SJeremy Kemp      *  \see Context::getDefault()
4362*6fee86a4SJeremy Kemp      */
Buffer(cl_mem_flags flags,size_type size,void * host_ptr=nullptr,cl_int * err=nullptr)4363*6fee86a4SJeremy Kemp     Buffer(
4364*6fee86a4SJeremy Kemp         cl_mem_flags flags,
4365*6fee86a4SJeremy Kemp         size_type size,
4366*6fee86a4SJeremy Kemp         void* host_ptr = nullptr,
4367*6fee86a4SJeremy Kemp         cl_int* err = nullptr) : Buffer(Context::getDefault(err), flags, size, host_ptr, err) { }
4368*6fee86a4SJeremy Kemp 
4369*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 300
4370*6fee86a4SJeremy Kemp     /*! \brief Constructs a Buffer in the default context and with specified properties.
4371*6fee86a4SJeremy Kemp      *
4372*6fee86a4SJeremy Kemp      *  Wraps clCreateBufferWithProperties().
4373*6fee86a4SJeremy Kemp      *
4374*6fee86a4SJeremy Kemp      *  \param properties Optional list of properties for the buffer object and
4375*6fee86a4SJeremy Kemp      *                    their corresponding values. The non-empty list must
4376*6fee86a4SJeremy Kemp      *                    end with 0.
4377*6fee86a4SJeremy Kemp      *  \param host_ptr Storage to be used if the CL_MEM_USE_HOST_PTR flag was
4378*6fee86a4SJeremy Kemp      *                  specified. Note alignment & exclusivity requirements.
4379*6fee86a4SJeremy Kemp      *
4380*6fee86a4SJeremy Kemp      *  \see Context::getDefault()
4381*6fee86a4SJeremy Kemp      */
Buffer(const vector<cl_mem_properties> & properties,cl_mem_flags flags,size_type size,void * host_ptr=nullptr,cl_int * err=nullptr)4382*6fee86a4SJeremy Kemp     Buffer(
4383*6fee86a4SJeremy Kemp         const vector<cl_mem_properties>& properties,
4384*6fee86a4SJeremy Kemp         cl_mem_flags flags,
4385*6fee86a4SJeremy Kemp         size_type size,
4386*6fee86a4SJeremy Kemp         void* host_ptr = nullptr,
4387*6fee86a4SJeremy Kemp         cl_int* err = nullptr) : Buffer(Context::getDefault(err), properties, flags, size, host_ptr, err) { }
4388*6fee86a4SJeremy Kemp #endif
4389*6fee86a4SJeremy Kemp 
4390*6fee86a4SJeremy Kemp     /*!
4391*6fee86a4SJeremy Kemp      * \brief Construct a Buffer from a host container via iterators.
4392*6fee86a4SJeremy Kemp      * IteratorType must be random access.
4393*6fee86a4SJeremy Kemp      * If useHostPtr is specified iterators must represent contiguous data.
4394*6fee86a4SJeremy Kemp      */
4395*6fee86a4SJeremy Kemp     template< typename IteratorType >
Buffer(IteratorType startIterator,IteratorType endIterator,bool readOnly,bool useHostPtr=false,cl_int * err=nullptr)4396*6fee86a4SJeremy Kemp     Buffer(
4397*6fee86a4SJeremy Kemp         IteratorType startIterator,
4398*6fee86a4SJeremy Kemp         IteratorType endIterator,
4399*6fee86a4SJeremy Kemp         bool readOnly,
4400*6fee86a4SJeremy Kemp         bool useHostPtr = false,
4401*6fee86a4SJeremy Kemp         cl_int* err = nullptr)
4402*6fee86a4SJeremy Kemp     {
4403*6fee86a4SJeremy Kemp         typedef typename std::iterator_traits<IteratorType>::value_type DataType;
4404*6fee86a4SJeremy Kemp         cl_int error;
4405*6fee86a4SJeremy Kemp 
4406*6fee86a4SJeremy Kemp         cl_mem_flags flags = 0;
4407*6fee86a4SJeremy Kemp         if( readOnly ) {
4408*6fee86a4SJeremy Kemp             flags |= CL_MEM_READ_ONLY;
4409*6fee86a4SJeremy Kemp         }
4410*6fee86a4SJeremy Kemp         else {
4411*6fee86a4SJeremy Kemp             flags |= CL_MEM_READ_WRITE;
4412*6fee86a4SJeremy Kemp         }
4413*6fee86a4SJeremy Kemp         if( useHostPtr ) {
4414*6fee86a4SJeremy Kemp             flags |= CL_MEM_USE_HOST_PTR;
4415*6fee86a4SJeremy Kemp         }
4416*6fee86a4SJeremy Kemp 
4417*6fee86a4SJeremy Kemp         size_type size = sizeof(DataType)*(endIterator - startIterator);
4418*6fee86a4SJeremy Kemp 
4419*6fee86a4SJeremy Kemp         Context context = Context::getDefault(err);
4420*6fee86a4SJeremy Kemp 
4421*6fee86a4SJeremy Kemp         if( useHostPtr ) {
4422*6fee86a4SJeremy Kemp             object_ = ::clCreateBuffer(context(), flags, size, const_cast<DataType*>(&*startIterator), &error);
4423*6fee86a4SJeremy Kemp         } else {
4424*6fee86a4SJeremy Kemp             object_ = ::clCreateBuffer(context(), flags, size, 0, &error);
4425*6fee86a4SJeremy Kemp         }
4426*6fee86a4SJeremy Kemp 
4427*6fee86a4SJeremy Kemp         detail::errHandler(error, __CREATE_BUFFER_ERR);
4428*6fee86a4SJeremy Kemp         if (err != nullptr) {
4429*6fee86a4SJeremy Kemp             *err = error;
4430*6fee86a4SJeremy Kemp         }
4431*6fee86a4SJeremy Kemp 
4432*6fee86a4SJeremy Kemp         if( !useHostPtr ) {
4433*6fee86a4SJeremy Kemp             error = cl::copy(startIterator, endIterator, *this);
4434*6fee86a4SJeremy Kemp             detail::errHandler(error, __CREATE_BUFFER_ERR);
4435*6fee86a4SJeremy Kemp             if (err != nullptr) {
4436*6fee86a4SJeremy Kemp                 *err = error;
4437*6fee86a4SJeremy Kemp             }
4438*6fee86a4SJeremy Kemp         }
4439*6fee86a4SJeremy Kemp     }
4440*6fee86a4SJeremy Kemp 
4441*6fee86a4SJeremy Kemp     /*!
4442*6fee86a4SJeremy Kemp      * \brief Construct a Buffer from a host container via iterators using a specified context.
4443*6fee86a4SJeremy Kemp      * IteratorType must be random access.
4444*6fee86a4SJeremy Kemp      * If useHostPtr is specified iterators must represent contiguous data.
4445*6fee86a4SJeremy Kemp      */
4446*6fee86a4SJeremy Kemp     template< typename IteratorType >
4447*6fee86a4SJeremy Kemp     Buffer(const Context &context, IteratorType startIterator, IteratorType endIterator,
4448*6fee86a4SJeremy Kemp         bool readOnly, bool useHostPtr = false, cl_int* err = nullptr);
4449*6fee86a4SJeremy Kemp 
4450*6fee86a4SJeremy Kemp     /*!
4451*6fee86a4SJeremy Kemp     * \brief Construct a Buffer from a host container via iterators using a specified queue.
4452*6fee86a4SJeremy Kemp     * If useHostPtr is specified iterators must be random access.
4453*6fee86a4SJeremy Kemp     */
4454*6fee86a4SJeremy Kemp     template< typename IteratorType >
4455*6fee86a4SJeremy Kemp     Buffer(const CommandQueue &queue, IteratorType startIterator, IteratorType endIterator,
4456*6fee86a4SJeremy Kemp         bool readOnly, bool useHostPtr = false, cl_int* err = nullptr);
4457*6fee86a4SJeremy Kemp 
4458*6fee86a4SJeremy Kemp     //! \brief Default constructor - initializes to nullptr.
Buffer()4459*6fee86a4SJeremy Kemp     Buffer() : Memory() { }
4460*6fee86a4SJeremy Kemp 
4461*6fee86a4SJeremy Kemp     /*! \brief Constructor from cl_mem - takes ownership.
4462*6fee86a4SJeremy Kemp      *
4463*6fee86a4SJeremy Kemp      * \param retainObject will cause the constructor to retain its cl object.
4464*6fee86a4SJeremy Kemp      *                     Defaults to false to maintain compatibility with earlier versions.
4465*6fee86a4SJeremy Kemp      *
4466*6fee86a4SJeremy Kemp      *  See Memory for further details.
4467*6fee86a4SJeremy Kemp      */
Buffer(const cl_mem & buffer,bool retainObject=false)4468*6fee86a4SJeremy Kemp     explicit Buffer(const cl_mem& buffer, bool retainObject = false) :
4469*6fee86a4SJeremy Kemp         Memory(buffer, retainObject) { }
4470*6fee86a4SJeremy Kemp 
4471*6fee86a4SJeremy Kemp     /*! \brief Assignment from cl_mem - performs shallow copy.
4472*6fee86a4SJeremy Kemp     *
4473*6fee86a4SJeremy Kemp     *  See Memory for further details.
4474*6fee86a4SJeremy Kemp     */
operator =(const cl_mem & rhs)4475*6fee86a4SJeremy Kemp     Buffer& operator = (const cl_mem& rhs)
4476*6fee86a4SJeremy Kemp     {
4477*6fee86a4SJeremy Kemp         Memory::operator=(rhs);
4478*6fee86a4SJeremy Kemp         return *this;
4479*6fee86a4SJeremy Kemp     }
4480*6fee86a4SJeremy Kemp 
4481*6fee86a4SJeremy Kemp 
4482*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 110
4483*6fee86a4SJeremy Kemp     /*! \brief Creates a new buffer object from this.
4484*6fee86a4SJeremy Kemp      *
4485*6fee86a4SJeremy Kemp      *  Wraps clCreateSubBuffer().
4486*6fee86a4SJeremy Kemp      */
createSubBuffer(cl_mem_flags flags,cl_buffer_create_type buffer_create_type,const void * buffer_create_info,cl_int * err=nullptr)4487*6fee86a4SJeremy Kemp     Buffer createSubBuffer(
4488*6fee86a4SJeremy Kemp         cl_mem_flags flags,
4489*6fee86a4SJeremy Kemp         cl_buffer_create_type buffer_create_type,
4490*6fee86a4SJeremy Kemp         const void * buffer_create_info,
4491*6fee86a4SJeremy Kemp         cl_int * err = nullptr)
4492*6fee86a4SJeremy Kemp     {
4493*6fee86a4SJeremy Kemp         Buffer result;
4494*6fee86a4SJeremy Kemp         cl_int error;
4495*6fee86a4SJeremy Kemp         result.object_ = ::clCreateSubBuffer(
4496*6fee86a4SJeremy Kemp             object_,
4497*6fee86a4SJeremy Kemp             flags,
4498*6fee86a4SJeremy Kemp             buffer_create_type,
4499*6fee86a4SJeremy Kemp             buffer_create_info,
4500*6fee86a4SJeremy Kemp             &error);
4501*6fee86a4SJeremy Kemp 
4502*6fee86a4SJeremy Kemp         detail::errHandler(error, __CREATE_SUBBUFFER_ERR);
4503*6fee86a4SJeremy Kemp         if (err != nullptr) {
4504*6fee86a4SJeremy Kemp             *err = error;
4505*6fee86a4SJeremy Kemp         }
4506*6fee86a4SJeremy Kemp 
4507*6fee86a4SJeremy Kemp         return result;
4508*6fee86a4SJeremy Kemp     }
4509*6fee86a4SJeremy Kemp #endif // CL_HPP_TARGET_OPENCL_VERSION >= 110
4510*6fee86a4SJeremy Kemp };
4511*6fee86a4SJeremy Kemp 
4512*6fee86a4SJeremy Kemp #if defined (CL_HPP_USE_DX_INTEROP)
4513*6fee86a4SJeremy Kemp /*! \brief Class interface for creating OpenCL buffers from ID3D10Buffer's.
4514*6fee86a4SJeremy Kemp  *
4515*6fee86a4SJeremy Kemp  *  This is provided to facilitate interoperability with Direct3D.
4516*6fee86a4SJeremy Kemp  *
4517*6fee86a4SJeremy Kemp  *  See Memory for details about copy semantics, etc.
4518*6fee86a4SJeremy Kemp  *
4519*6fee86a4SJeremy Kemp  *  \see Memory
4520*6fee86a4SJeremy Kemp  */
4521*6fee86a4SJeremy Kemp class BufferD3D10 : public Buffer
4522*6fee86a4SJeremy Kemp {
4523*6fee86a4SJeremy Kemp public:
4524*6fee86a4SJeremy Kemp 
4525*6fee86a4SJeremy Kemp 
4526*6fee86a4SJeremy Kemp     /*! \brief Constructs a BufferD3D10, in a specified context, from a
4527*6fee86a4SJeremy Kemp      *         given ID3D10Buffer.
4528*6fee86a4SJeremy Kemp      *
4529*6fee86a4SJeremy Kemp      *  Wraps clCreateFromD3D10BufferKHR().
4530*6fee86a4SJeremy Kemp      */
BufferD3D10(const Context & context,cl_mem_flags flags,ID3D10Buffer * bufobj,cl_int * err=nullptr)4531*6fee86a4SJeremy Kemp     BufferD3D10(
4532*6fee86a4SJeremy Kemp         const Context& context,
4533*6fee86a4SJeremy Kemp         cl_mem_flags flags,
4534*6fee86a4SJeremy Kemp         ID3D10Buffer* bufobj,
4535*6fee86a4SJeremy Kemp         cl_int * err = nullptr) : pfn_clCreateFromD3D10BufferKHR(nullptr)
4536*6fee86a4SJeremy Kemp     {
4537*6fee86a4SJeremy Kemp         typedef CL_API_ENTRY cl_mem (CL_API_CALL *PFN_clCreateFromD3D10BufferKHR)(
4538*6fee86a4SJeremy Kemp             cl_context context, cl_mem_flags flags, ID3D10Buffer*  buffer,
4539*6fee86a4SJeremy Kemp             cl_int* errcode_ret);
4540*6fee86a4SJeremy Kemp         PFN_clCreateFromD3D10BufferKHR pfn_clCreateFromD3D10BufferKHR;
4541*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 120
4542*6fee86a4SJeremy Kemp         vector<cl_context_properties> props = context.getInfo<CL_CONTEXT_PROPERTIES>();
4543*6fee86a4SJeremy Kemp         cl_platform platform = nullptr;
4544*6fee86a4SJeremy Kemp         for( int i = 0; i < props.size(); ++i ) {
4545*6fee86a4SJeremy Kemp             if( props[i] == CL_CONTEXT_PLATFORM ) {
4546*6fee86a4SJeremy Kemp                 platform = props[i+1];
4547*6fee86a4SJeremy Kemp             }
4548*6fee86a4SJeremy Kemp         }
4549*6fee86a4SJeremy Kemp         CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clCreateFromD3D10BufferKHR);
4550*6fee86a4SJeremy Kemp #endif
4551*6fee86a4SJeremy Kemp #if CL_HPP_MINIMUM_OPENCL_VERSION < 120
4552*6fee86a4SJeremy Kemp         CL_HPP_INIT_CL_EXT_FCN_PTR_(clCreateFromD3D10BufferKHR);
4553*6fee86a4SJeremy Kemp #endif
4554*6fee86a4SJeremy Kemp 
4555*6fee86a4SJeremy Kemp         cl_int error;
4556*6fee86a4SJeremy Kemp         object_ = pfn_clCreateFromD3D10BufferKHR(
4557*6fee86a4SJeremy Kemp             context(),
4558*6fee86a4SJeremy Kemp             flags,
4559*6fee86a4SJeremy Kemp             bufobj,
4560*6fee86a4SJeremy Kemp             &error);
4561*6fee86a4SJeremy Kemp 
4562*6fee86a4SJeremy Kemp         // TODO: This should really have a D3D10 rerror code!
4563*6fee86a4SJeremy Kemp         detail::errHandler(error, __CREATE_GL_BUFFER_ERR);
4564*6fee86a4SJeremy Kemp         if (err != nullptr) {
4565*6fee86a4SJeremy Kemp             *err = error;
4566*6fee86a4SJeremy Kemp         }
4567*6fee86a4SJeremy Kemp     }
4568*6fee86a4SJeremy Kemp 
4569*6fee86a4SJeremy Kemp     //! \brief Default constructor - initializes to nullptr.
BufferD3D10()4570*6fee86a4SJeremy Kemp     BufferD3D10() : Buffer() { }
4571*6fee86a4SJeremy Kemp 
4572*6fee86a4SJeremy Kemp     /*! \brief Constructor from cl_mem - takes ownership.
4573*6fee86a4SJeremy Kemp      *
4574*6fee86a4SJeremy Kemp      * \param retainObject will cause the constructor to retain its cl object.
4575*6fee86a4SJeremy Kemp      *                     Defaults to false to maintain compatibility with
4576*6fee86a4SJeremy Kemp      *                     earlier versions.
4577*6fee86a4SJeremy Kemp      *  See Memory for further details.
4578*6fee86a4SJeremy Kemp      */
BufferD3D10(const cl_mem & buffer,bool retainObject=false)4579*6fee86a4SJeremy Kemp     explicit BufferD3D10(const cl_mem& buffer, bool retainObject = false) :
4580*6fee86a4SJeremy Kemp         Buffer(buffer, retainObject) { }
4581*6fee86a4SJeremy Kemp 
4582*6fee86a4SJeremy Kemp     /*! \brief Assignment from cl_mem - performs shallow copy.
4583*6fee86a4SJeremy Kemp      *
4584*6fee86a4SJeremy Kemp      *  See Memory for further details.
4585*6fee86a4SJeremy Kemp      */
operator =(const cl_mem & rhs)4586*6fee86a4SJeremy Kemp     BufferD3D10& operator = (const cl_mem& rhs)
4587*6fee86a4SJeremy Kemp     {
4588*6fee86a4SJeremy Kemp         Buffer::operator=(rhs);
4589*6fee86a4SJeremy Kemp         return *this;
4590*6fee86a4SJeremy Kemp     }
4591*6fee86a4SJeremy Kemp };
4592*6fee86a4SJeremy Kemp #endif
4593*6fee86a4SJeremy Kemp 
4594*6fee86a4SJeremy Kemp /*! \brief Class interface for GL Buffer Memory Objects.
4595*6fee86a4SJeremy Kemp  *
4596*6fee86a4SJeremy Kemp  *  This is provided to facilitate interoperability with OpenGL.
4597*6fee86a4SJeremy Kemp  *
4598*6fee86a4SJeremy Kemp  *  See Memory for details about copy semantics, etc.
4599*6fee86a4SJeremy Kemp  *
4600*6fee86a4SJeremy Kemp  *  \see Memory
4601*6fee86a4SJeremy Kemp  */
4602*6fee86a4SJeremy Kemp class BufferGL : public Buffer
4603*6fee86a4SJeremy Kemp {
4604*6fee86a4SJeremy Kemp public:
4605*6fee86a4SJeremy Kemp     /*! \brief Constructs a BufferGL in a specified context, from a given
4606*6fee86a4SJeremy Kemp      *         GL buffer.
4607*6fee86a4SJeremy Kemp      *
4608*6fee86a4SJeremy Kemp      *  Wraps clCreateFromGLBuffer().
4609*6fee86a4SJeremy Kemp      */
BufferGL(const Context & context,cl_mem_flags flags,cl_GLuint bufobj,cl_int * err=nullptr)4610*6fee86a4SJeremy Kemp     BufferGL(
4611*6fee86a4SJeremy Kemp         const Context& context,
4612*6fee86a4SJeremy Kemp         cl_mem_flags flags,
4613*6fee86a4SJeremy Kemp         cl_GLuint bufobj,
4614*6fee86a4SJeremy Kemp         cl_int * err = nullptr)
4615*6fee86a4SJeremy Kemp     {
4616*6fee86a4SJeremy Kemp         cl_int error;
4617*6fee86a4SJeremy Kemp         object_ = ::clCreateFromGLBuffer(
4618*6fee86a4SJeremy Kemp             context(),
4619*6fee86a4SJeremy Kemp             flags,
4620*6fee86a4SJeremy Kemp             bufobj,
4621*6fee86a4SJeremy Kemp             &error);
4622*6fee86a4SJeremy Kemp 
4623*6fee86a4SJeremy Kemp         detail::errHandler(error, __CREATE_GL_BUFFER_ERR);
4624*6fee86a4SJeremy Kemp         if (err != nullptr) {
4625*6fee86a4SJeremy Kemp             *err = error;
4626*6fee86a4SJeremy Kemp         }
4627*6fee86a4SJeremy Kemp     }
4628*6fee86a4SJeremy Kemp 
4629*6fee86a4SJeremy Kemp     //! \brief Default constructor - initializes to nullptr.
BufferGL()4630*6fee86a4SJeremy Kemp     BufferGL() : Buffer() { }
4631*6fee86a4SJeremy Kemp 
4632*6fee86a4SJeremy Kemp     /*! \brief Constructor from cl_mem - takes ownership.
4633*6fee86a4SJeremy Kemp      *
4634*6fee86a4SJeremy Kemp      * \param retainObject will cause the constructor to retain its cl object.
4635*6fee86a4SJeremy Kemp      *                     Defaults to false to maintain compatibility with
4636*6fee86a4SJeremy Kemp      *                     earlier versions.
4637*6fee86a4SJeremy Kemp      *  See Memory for further details.
4638*6fee86a4SJeremy Kemp      */
BufferGL(const cl_mem & buffer,bool retainObject=false)4639*6fee86a4SJeremy Kemp     explicit BufferGL(const cl_mem& buffer, bool retainObject = false) :
4640*6fee86a4SJeremy Kemp         Buffer(buffer, retainObject) { }
4641*6fee86a4SJeremy Kemp 
4642*6fee86a4SJeremy Kemp     /*! \brief Assignment from cl_mem - performs shallow copy.
4643*6fee86a4SJeremy Kemp      *
4644*6fee86a4SJeremy Kemp      *  See Memory for further details.
4645*6fee86a4SJeremy Kemp      */
operator =(const cl_mem & rhs)4646*6fee86a4SJeremy Kemp     BufferGL& operator = (const cl_mem& rhs)
4647*6fee86a4SJeremy Kemp     {
4648*6fee86a4SJeremy Kemp         Buffer::operator=(rhs);
4649*6fee86a4SJeremy Kemp         return *this;
4650*6fee86a4SJeremy Kemp     }
4651*6fee86a4SJeremy Kemp 
4652*6fee86a4SJeremy Kemp 
4653*6fee86a4SJeremy Kemp     //! \brief Wrapper for clGetGLObjectInfo().
getObjectInfo(cl_gl_object_type * type,cl_GLuint * gl_object_name)4654*6fee86a4SJeremy Kemp     cl_int getObjectInfo(
4655*6fee86a4SJeremy Kemp         cl_gl_object_type *type,
4656*6fee86a4SJeremy Kemp         cl_GLuint * gl_object_name)
4657*6fee86a4SJeremy Kemp     {
4658*6fee86a4SJeremy Kemp         return detail::errHandler(
4659*6fee86a4SJeremy Kemp             ::clGetGLObjectInfo(object_,type,gl_object_name),
4660*6fee86a4SJeremy Kemp             __GET_GL_OBJECT_INFO_ERR);
4661*6fee86a4SJeremy Kemp     }
4662*6fee86a4SJeremy Kemp };
4663*6fee86a4SJeremy Kemp 
4664*6fee86a4SJeremy Kemp /*! \brief Class interface for GL Render Buffer Memory Objects.
4665*6fee86a4SJeremy Kemp  *
4666*6fee86a4SJeremy Kemp  *  This is provided to facilitate interoperability with OpenGL.
4667*6fee86a4SJeremy Kemp  *
4668*6fee86a4SJeremy Kemp  *  See Memory for details about copy semantics, etc.
4669*6fee86a4SJeremy Kemp  *
4670*6fee86a4SJeremy Kemp  *  \see Memory
4671*6fee86a4SJeremy Kemp  */
4672*6fee86a4SJeremy Kemp class BufferRenderGL : public Buffer
4673*6fee86a4SJeremy Kemp {
4674*6fee86a4SJeremy Kemp public:
4675*6fee86a4SJeremy Kemp     /*! \brief Constructs a BufferRenderGL in a specified context, from a given
4676*6fee86a4SJeremy Kemp      *         GL Renderbuffer.
4677*6fee86a4SJeremy Kemp      *
4678*6fee86a4SJeremy Kemp      *  Wraps clCreateFromGLRenderbuffer().
4679*6fee86a4SJeremy Kemp      */
BufferRenderGL(const Context & context,cl_mem_flags flags,cl_GLuint bufobj,cl_int * err=nullptr)4680*6fee86a4SJeremy Kemp     BufferRenderGL(
4681*6fee86a4SJeremy Kemp         const Context& context,
4682*6fee86a4SJeremy Kemp         cl_mem_flags flags,
4683*6fee86a4SJeremy Kemp         cl_GLuint bufobj,
4684*6fee86a4SJeremy Kemp         cl_int * err = nullptr)
4685*6fee86a4SJeremy Kemp     {
4686*6fee86a4SJeremy Kemp         cl_int error;
4687*6fee86a4SJeremy Kemp         object_ = ::clCreateFromGLRenderbuffer(
4688*6fee86a4SJeremy Kemp             context(),
4689*6fee86a4SJeremy Kemp             flags,
4690*6fee86a4SJeremy Kemp             bufobj,
4691*6fee86a4SJeremy Kemp             &error);
4692*6fee86a4SJeremy Kemp 
4693*6fee86a4SJeremy Kemp         detail::errHandler(error, __CREATE_GL_RENDER_BUFFER_ERR);
4694*6fee86a4SJeremy Kemp         if (err != nullptr) {
4695*6fee86a4SJeremy Kemp             *err = error;
4696*6fee86a4SJeremy Kemp         }
4697*6fee86a4SJeremy Kemp     }
4698*6fee86a4SJeremy Kemp 
4699*6fee86a4SJeremy Kemp     //! \brief Default constructor - initializes to nullptr.
BufferRenderGL()4700*6fee86a4SJeremy Kemp     BufferRenderGL() : Buffer() { }
4701*6fee86a4SJeremy Kemp 
4702*6fee86a4SJeremy Kemp     /*! \brief Constructor from cl_mem - takes ownership.
4703*6fee86a4SJeremy Kemp      *
4704*6fee86a4SJeremy Kemp      * \param retainObject will cause the constructor to retain its cl object.
4705*6fee86a4SJeremy Kemp      *                     Defaults to false to maintain compatibility with
4706*6fee86a4SJeremy Kemp      *                     earlier versions.
4707*6fee86a4SJeremy Kemp      *  See Memory for further details.
4708*6fee86a4SJeremy Kemp      */
BufferRenderGL(const cl_mem & buffer,bool retainObject=false)4709*6fee86a4SJeremy Kemp     explicit BufferRenderGL(const cl_mem& buffer, bool retainObject = false) :
4710*6fee86a4SJeremy Kemp         Buffer(buffer, retainObject) { }
4711*6fee86a4SJeremy Kemp 
4712*6fee86a4SJeremy Kemp     /*! \brief Assignment from cl_mem - performs shallow copy.
4713*6fee86a4SJeremy Kemp      *
4714*6fee86a4SJeremy Kemp      *  See Memory for further details.
4715*6fee86a4SJeremy Kemp      */
operator =(const cl_mem & rhs)4716*6fee86a4SJeremy Kemp     BufferRenderGL& operator = (const cl_mem& rhs)
4717*6fee86a4SJeremy Kemp     {
4718*6fee86a4SJeremy Kemp         Buffer::operator=(rhs);
4719*6fee86a4SJeremy Kemp         return *this;
4720*6fee86a4SJeremy Kemp     }
4721*6fee86a4SJeremy Kemp 
4722*6fee86a4SJeremy Kemp 
4723*6fee86a4SJeremy Kemp     //! \brief Wrapper for clGetGLObjectInfo().
getObjectInfo(cl_gl_object_type * type,cl_GLuint * gl_object_name)4724*6fee86a4SJeremy Kemp     cl_int getObjectInfo(
4725*6fee86a4SJeremy Kemp         cl_gl_object_type *type,
4726*6fee86a4SJeremy Kemp         cl_GLuint * gl_object_name)
4727*6fee86a4SJeremy Kemp     {
4728*6fee86a4SJeremy Kemp         return detail::errHandler(
4729*6fee86a4SJeremy Kemp             ::clGetGLObjectInfo(object_,type,gl_object_name),
4730*6fee86a4SJeremy Kemp             __GET_GL_OBJECT_INFO_ERR);
4731*6fee86a4SJeremy Kemp     }
4732*6fee86a4SJeremy Kemp };
4733*6fee86a4SJeremy Kemp 
4734*6fee86a4SJeremy Kemp /*! \brief C++ base class for Image Memory objects.
4735*6fee86a4SJeremy Kemp  *
4736*6fee86a4SJeremy Kemp  *  See Memory for details about copy semantics, etc.
4737*6fee86a4SJeremy Kemp  *
4738*6fee86a4SJeremy Kemp  *  \see Memory
4739*6fee86a4SJeremy Kemp  */
4740*6fee86a4SJeremy Kemp class Image : public Memory
4741*6fee86a4SJeremy Kemp {
4742*6fee86a4SJeremy Kemp protected:
4743*6fee86a4SJeremy Kemp     //! \brief Default constructor - initializes to nullptr.
Image()4744*6fee86a4SJeremy Kemp     Image() : Memory() { }
4745*6fee86a4SJeremy Kemp 
4746*6fee86a4SJeremy Kemp     /*! \brief Constructor from cl_mem - takes ownership.
4747*6fee86a4SJeremy Kemp      *
4748*6fee86a4SJeremy Kemp      * \param retainObject will cause the constructor to retain its cl object.
4749*6fee86a4SJeremy Kemp      *                     Defaults to false to maintain compatibility with
4750*6fee86a4SJeremy Kemp      *                     earlier versions.
4751*6fee86a4SJeremy Kemp      *  See Memory for further details.
4752*6fee86a4SJeremy Kemp      */
Image(const cl_mem & image,bool retainObject=false)4753*6fee86a4SJeremy Kemp     explicit Image(const cl_mem& image, bool retainObject = false) :
4754*6fee86a4SJeremy Kemp         Memory(image, retainObject) { }
4755*6fee86a4SJeremy Kemp 
4756*6fee86a4SJeremy Kemp     /*! \brief Assignment from cl_mem - performs shallow copy.
4757*6fee86a4SJeremy Kemp      *
4758*6fee86a4SJeremy Kemp      *  See Memory for further details.
4759*6fee86a4SJeremy Kemp      */
operator =(const cl_mem & rhs)4760*6fee86a4SJeremy Kemp     Image& operator = (const cl_mem& rhs)
4761*6fee86a4SJeremy Kemp     {
4762*6fee86a4SJeremy Kemp         Memory::operator=(rhs);
4763*6fee86a4SJeremy Kemp         return *this;
4764*6fee86a4SJeremy Kemp     }
4765*6fee86a4SJeremy Kemp 
4766*6fee86a4SJeremy Kemp 
4767*6fee86a4SJeremy Kemp public:
4768*6fee86a4SJeremy Kemp     //! \brief Wrapper for clGetImageInfo().
4769*6fee86a4SJeremy Kemp     template <typename T>
getImageInfo(cl_image_info name,T * param) const4770*6fee86a4SJeremy Kemp     cl_int getImageInfo(cl_image_info name, T* param) const
4771*6fee86a4SJeremy Kemp     {
4772*6fee86a4SJeremy Kemp         return detail::errHandler(
4773*6fee86a4SJeremy Kemp             detail::getInfo(&::clGetImageInfo, object_, name, param),
4774*6fee86a4SJeremy Kemp             __GET_IMAGE_INFO_ERR);
4775*6fee86a4SJeremy Kemp     }
4776*6fee86a4SJeremy Kemp 
4777*6fee86a4SJeremy Kemp     //! \brief Wrapper for clGetImageInfo() that returns by value.
4778*6fee86a4SJeremy Kemp     template <cl_image_info name> typename
4779*6fee86a4SJeremy Kemp     detail::param_traits<detail::cl_image_info, name>::param_type
getImageInfo(cl_int * err=nullptr) const4780*6fee86a4SJeremy Kemp     getImageInfo(cl_int* err = nullptr) const
4781*6fee86a4SJeremy Kemp     {
4782*6fee86a4SJeremy Kemp         typename detail::param_traits<
4783*6fee86a4SJeremy Kemp             detail::cl_image_info, name>::param_type param;
4784*6fee86a4SJeremy Kemp         cl_int result = getImageInfo(name, &param);
4785*6fee86a4SJeremy Kemp         if (err != nullptr) {
4786*6fee86a4SJeremy Kemp             *err = result;
4787*6fee86a4SJeremy Kemp         }
4788*6fee86a4SJeremy Kemp         return param;
4789*6fee86a4SJeremy Kemp     }
4790*6fee86a4SJeremy Kemp };
4791*6fee86a4SJeremy Kemp 
4792*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 120
4793*6fee86a4SJeremy Kemp /*! \brief Class interface for 1D Image Memory objects.
4794*6fee86a4SJeremy Kemp  *
4795*6fee86a4SJeremy Kemp  *  See Memory for details about copy semantics, etc.
4796*6fee86a4SJeremy Kemp  *
4797*6fee86a4SJeremy Kemp  *  \see Memory
4798*6fee86a4SJeremy Kemp  */
4799*6fee86a4SJeremy Kemp class Image1D : public Image
4800*6fee86a4SJeremy Kemp {
4801*6fee86a4SJeremy Kemp public:
4802*6fee86a4SJeremy Kemp     /*! \brief Constructs a 1D Image in a specified context.
4803*6fee86a4SJeremy Kemp      *
4804*6fee86a4SJeremy Kemp      *  Wraps clCreateImage().
4805*6fee86a4SJeremy Kemp      */
Image1D(const Context & context,cl_mem_flags flags,ImageFormat format,size_type width,void * host_ptr=nullptr,cl_int * err=nullptr)4806*6fee86a4SJeremy Kemp     Image1D(
4807*6fee86a4SJeremy Kemp         const Context& context,
4808*6fee86a4SJeremy Kemp         cl_mem_flags flags,
4809*6fee86a4SJeremy Kemp         ImageFormat format,
4810*6fee86a4SJeremy Kemp         size_type width,
4811*6fee86a4SJeremy Kemp         void* host_ptr = nullptr,
4812*6fee86a4SJeremy Kemp         cl_int* err = nullptr)
4813*6fee86a4SJeremy Kemp     {
4814*6fee86a4SJeremy Kemp         cl_int error;
4815*6fee86a4SJeremy Kemp 
4816*6fee86a4SJeremy Kemp         cl_image_desc desc = {};
4817*6fee86a4SJeremy Kemp         desc.image_type = CL_MEM_OBJECT_IMAGE1D;
4818*6fee86a4SJeremy Kemp         desc.image_width = width;
4819*6fee86a4SJeremy Kemp 
4820*6fee86a4SJeremy Kemp         object_ = ::clCreateImage(
4821*6fee86a4SJeremy Kemp             context(),
4822*6fee86a4SJeremy Kemp             flags,
4823*6fee86a4SJeremy Kemp             &format,
4824*6fee86a4SJeremy Kemp             &desc,
4825*6fee86a4SJeremy Kemp             host_ptr,
4826*6fee86a4SJeremy Kemp             &error);
4827*6fee86a4SJeremy Kemp 
4828*6fee86a4SJeremy Kemp         detail::errHandler(error, __CREATE_IMAGE_ERR);
4829*6fee86a4SJeremy Kemp         if (err != nullptr) {
4830*6fee86a4SJeremy Kemp             *err = error;
4831*6fee86a4SJeremy Kemp         }
4832*6fee86a4SJeremy Kemp     }
4833*6fee86a4SJeremy Kemp 
4834*6fee86a4SJeremy Kemp     //! \brief Default constructor - initializes to nullptr.
Image1D()4835*6fee86a4SJeremy Kemp     Image1D() { }
4836*6fee86a4SJeremy Kemp 
4837*6fee86a4SJeremy Kemp     /*! \brief Constructor from cl_mem - takes ownership.
4838*6fee86a4SJeremy Kemp      *
4839*6fee86a4SJeremy Kemp      * \param retainObject will cause the constructor to retain its cl object.
4840*6fee86a4SJeremy Kemp      *                     Defaults to false to maintain compatibility with
4841*6fee86a4SJeremy Kemp      *                     earlier versions.
4842*6fee86a4SJeremy Kemp      *  See Memory for further details.
4843*6fee86a4SJeremy Kemp      */
Image1D(const cl_mem & image1D,bool retainObject=false)4844*6fee86a4SJeremy Kemp     explicit Image1D(const cl_mem& image1D, bool retainObject = false) :
4845*6fee86a4SJeremy Kemp         Image(image1D, retainObject) { }
4846*6fee86a4SJeremy Kemp 
4847*6fee86a4SJeremy Kemp     /*! \brief Assignment from cl_mem - performs shallow copy.
4848*6fee86a4SJeremy Kemp      *
4849*6fee86a4SJeremy Kemp      *  See Memory for further details.
4850*6fee86a4SJeremy Kemp      */
operator =(const cl_mem & rhs)4851*6fee86a4SJeremy Kemp     Image1D& operator = (const cl_mem& rhs)
4852*6fee86a4SJeremy Kemp     {
4853*6fee86a4SJeremy Kemp         Image::operator=(rhs);
4854*6fee86a4SJeremy Kemp         return *this;
4855*6fee86a4SJeremy Kemp     }
4856*6fee86a4SJeremy Kemp 
4857*6fee86a4SJeremy Kemp 
4858*6fee86a4SJeremy Kemp };
4859*6fee86a4SJeremy Kemp 
4860*6fee86a4SJeremy Kemp /*! \class Image1DBuffer
4861*6fee86a4SJeremy Kemp  * \brief Image interface for 1D buffer images.
4862*6fee86a4SJeremy Kemp  */
4863*6fee86a4SJeremy Kemp class Image1DBuffer : public Image
4864*6fee86a4SJeremy Kemp {
4865*6fee86a4SJeremy Kemp public:
Image1DBuffer(const Context & context,cl_mem_flags flags,ImageFormat format,size_type width,const Buffer & buffer,cl_int * err=nullptr)4866*6fee86a4SJeremy Kemp     Image1DBuffer(
4867*6fee86a4SJeremy Kemp         const Context& context,
4868*6fee86a4SJeremy Kemp         cl_mem_flags flags,
4869*6fee86a4SJeremy Kemp         ImageFormat format,
4870*6fee86a4SJeremy Kemp         size_type width,
4871*6fee86a4SJeremy Kemp         const Buffer &buffer,
4872*6fee86a4SJeremy Kemp         cl_int* err = nullptr)
4873*6fee86a4SJeremy Kemp     {
4874*6fee86a4SJeremy Kemp         cl_int error;
4875*6fee86a4SJeremy Kemp 
4876*6fee86a4SJeremy Kemp         cl_image_desc desc = {};
4877*6fee86a4SJeremy Kemp         desc.image_type = CL_MEM_OBJECT_IMAGE1D_BUFFER;
4878*6fee86a4SJeremy Kemp         desc.image_width = width;
4879*6fee86a4SJeremy Kemp         desc.buffer = buffer();
4880*6fee86a4SJeremy Kemp 
4881*6fee86a4SJeremy Kemp         object_ = ::clCreateImage(
4882*6fee86a4SJeremy Kemp             context(),
4883*6fee86a4SJeremy Kemp             flags,
4884*6fee86a4SJeremy Kemp             &format,
4885*6fee86a4SJeremy Kemp             &desc,
4886*6fee86a4SJeremy Kemp             nullptr,
4887*6fee86a4SJeremy Kemp             &error);
4888*6fee86a4SJeremy Kemp 
4889*6fee86a4SJeremy Kemp         detail::errHandler(error, __CREATE_IMAGE_ERR);
4890*6fee86a4SJeremy Kemp         if (err != nullptr) {
4891*6fee86a4SJeremy Kemp             *err = error;
4892*6fee86a4SJeremy Kemp         }
4893*6fee86a4SJeremy Kemp     }
4894*6fee86a4SJeremy Kemp 
Image1DBuffer()4895*6fee86a4SJeremy Kemp     Image1DBuffer() { }
4896*6fee86a4SJeremy Kemp 
4897*6fee86a4SJeremy Kemp     /*! \brief Constructor from cl_mem - takes ownership.
4898*6fee86a4SJeremy Kemp      *
4899*6fee86a4SJeremy Kemp      * \param retainObject will cause the constructor to retain its cl object.
4900*6fee86a4SJeremy Kemp      *                     Defaults to false to maintain compatibility with
4901*6fee86a4SJeremy Kemp      *                     earlier versions.
4902*6fee86a4SJeremy Kemp      *  See Memory for further details.
4903*6fee86a4SJeremy Kemp      */
Image1DBuffer(const cl_mem & image1D,bool retainObject=false)4904*6fee86a4SJeremy Kemp     explicit Image1DBuffer(const cl_mem& image1D, bool retainObject = false) :
4905*6fee86a4SJeremy Kemp         Image(image1D, retainObject) { }
4906*6fee86a4SJeremy Kemp 
operator =(const cl_mem & rhs)4907*6fee86a4SJeremy Kemp     Image1DBuffer& operator = (const cl_mem& rhs)
4908*6fee86a4SJeremy Kemp     {
4909*6fee86a4SJeremy Kemp         Image::operator=(rhs);
4910*6fee86a4SJeremy Kemp         return *this;
4911*6fee86a4SJeremy Kemp     }
4912*6fee86a4SJeremy Kemp 
4913*6fee86a4SJeremy Kemp 
4914*6fee86a4SJeremy Kemp 
4915*6fee86a4SJeremy Kemp };
4916*6fee86a4SJeremy Kemp 
4917*6fee86a4SJeremy Kemp /*! \class Image1DArray
4918*6fee86a4SJeremy Kemp  * \brief Image interface for arrays of 1D images.
4919*6fee86a4SJeremy Kemp  */
4920*6fee86a4SJeremy Kemp class Image1DArray : public Image
4921*6fee86a4SJeremy Kemp {
4922*6fee86a4SJeremy Kemp public:
Image1DArray(const Context & context,cl_mem_flags flags,ImageFormat format,size_type arraySize,size_type width,size_type rowPitch,void * host_ptr=nullptr,cl_int * err=nullptr)4923*6fee86a4SJeremy Kemp     Image1DArray(
4924*6fee86a4SJeremy Kemp         const Context& context,
4925*6fee86a4SJeremy Kemp         cl_mem_flags flags,
4926*6fee86a4SJeremy Kemp         ImageFormat format,
4927*6fee86a4SJeremy Kemp         size_type arraySize,
4928*6fee86a4SJeremy Kemp         size_type width,
4929*6fee86a4SJeremy Kemp         size_type rowPitch,
4930*6fee86a4SJeremy Kemp         void* host_ptr = nullptr,
4931*6fee86a4SJeremy Kemp         cl_int* err = nullptr)
4932*6fee86a4SJeremy Kemp     {
4933*6fee86a4SJeremy Kemp         cl_int error;
4934*6fee86a4SJeremy Kemp 
4935*6fee86a4SJeremy Kemp         cl_image_desc desc = {};
4936*6fee86a4SJeremy Kemp         desc.image_type = CL_MEM_OBJECT_IMAGE1D_ARRAY;
4937*6fee86a4SJeremy Kemp         desc.image_width = width;
4938*6fee86a4SJeremy Kemp         desc.image_array_size = arraySize;
4939*6fee86a4SJeremy Kemp         desc.image_row_pitch = rowPitch;
4940*6fee86a4SJeremy Kemp 
4941*6fee86a4SJeremy Kemp         object_ = ::clCreateImage(
4942*6fee86a4SJeremy Kemp             context(),
4943*6fee86a4SJeremy Kemp             flags,
4944*6fee86a4SJeremy Kemp             &format,
4945*6fee86a4SJeremy Kemp             &desc,
4946*6fee86a4SJeremy Kemp             host_ptr,
4947*6fee86a4SJeremy Kemp             &error);
4948*6fee86a4SJeremy Kemp 
4949*6fee86a4SJeremy Kemp         detail::errHandler(error, __CREATE_IMAGE_ERR);
4950*6fee86a4SJeremy Kemp         if (err != nullptr) {
4951*6fee86a4SJeremy Kemp             *err = error;
4952*6fee86a4SJeremy Kemp         }
4953*6fee86a4SJeremy Kemp     }
4954*6fee86a4SJeremy Kemp 
Image1DArray()4955*6fee86a4SJeremy Kemp     Image1DArray() { }
4956*6fee86a4SJeremy Kemp 
4957*6fee86a4SJeremy Kemp     /*! \brief Constructor from cl_mem - takes ownership.
4958*6fee86a4SJeremy Kemp      *
4959*6fee86a4SJeremy Kemp      * \param retainObject will cause the constructor to retain its cl object.
4960*6fee86a4SJeremy Kemp      *                     Defaults to false to maintain compatibility with
4961*6fee86a4SJeremy Kemp      *                     earlier versions.
4962*6fee86a4SJeremy Kemp      *  See Memory for further details.
4963*6fee86a4SJeremy Kemp      */
Image1DArray(const cl_mem & imageArray,bool retainObject=false)4964*6fee86a4SJeremy Kemp     explicit Image1DArray(const cl_mem& imageArray, bool retainObject = false) :
4965*6fee86a4SJeremy Kemp         Image(imageArray, retainObject) { }
4966*6fee86a4SJeremy Kemp 
4967*6fee86a4SJeremy Kemp 
operator =(const cl_mem & rhs)4968*6fee86a4SJeremy Kemp     Image1DArray& operator = (const cl_mem& rhs)
4969*6fee86a4SJeremy Kemp     {
4970*6fee86a4SJeremy Kemp         Image::operator=(rhs);
4971*6fee86a4SJeremy Kemp         return *this;
4972*6fee86a4SJeremy Kemp     }
4973*6fee86a4SJeremy Kemp 
4974*6fee86a4SJeremy Kemp 
4975*6fee86a4SJeremy Kemp };
4976*6fee86a4SJeremy Kemp #endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 120
4977*6fee86a4SJeremy Kemp 
4978*6fee86a4SJeremy Kemp 
4979*6fee86a4SJeremy Kemp /*! \brief Class interface for 2D Image Memory objects.
4980*6fee86a4SJeremy Kemp  *
4981*6fee86a4SJeremy Kemp  *  See Memory for details about copy semantics, etc.
4982*6fee86a4SJeremy Kemp  *
4983*6fee86a4SJeremy Kemp  *  \see Memory
4984*6fee86a4SJeremy Kemp  */
4985*6fee86a4SJeremy Kemp class Image2D : public Image
4986*6fee86a4SJeremy Kemp {
4987*6fee86a4SJeremy Kemp public:
4988*6fee86a4SJeremy Kemp     /*! \brief Constructs a 2D Image in a specified context.
4989*6fee86a4SJeremy Kemp      *
4990*6fee86a4SJeremy Kemp      *  Wraps clCreateImage().
4991*6fee86a4SJeremy Kemp      */
Image2D(const Context & context,cl_mem_flags flags,ImageFormat format,size_type width,size_type height,size_type row_pitch=0,void * host_ptr=nullptr,cl_int * err=nullptr)4992*6fee86a4SJeremy Kemp     Image2D(
4993*6fee86a4SJeremy Kemp         const Context& context,
4994*6fee86a4SJeremy Kemp         cl_mem_flags flags,
4995*6fee86a4SJeremy Kemp         ImageFormat format,
4996*6fee86a4SJeremy Kemp         size_type width,
4997*6fee86a4SJeremy Kemp         size_type height,
4998*6fee86a4SJeremy Kemp         size_type row_pitch = 0,
4999*6fee86a4SJeremy Kemp         void* host_ptr = nullptr,
5000*6fee86a4SJeremy Kemp         cl_int* err = nullptr)
5001*6fee86a4SJeremy Kemp     {
5002*6fee86a4SJeremy Kemp         cl_int error;
5003*6fee86a4SJeremy Kemp         bool useCreateImage;
5004*6fee86a4SJeremy Kemp 
5005*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 120 && CL_HPP_MINIMUM_OPENCL_VERSION < 120
5006*6fee86a4SJeremy Kemp         // Run-time decision based on the actual platform
5007*6fee86a4SJeremy Kemp         {
5008*6fee86a4SJeremy Kemp             cl_uint version = detail::getContextPlatformVersion(context());
5009*6fee86a4SJeremy Kemp             useCreateImage = (version >= 0x10002); // OpenCL 1.2 or above
5010*6fee86a4SJeremy Kemp         }
5011*6fee86a4SJeremy Kemp #elif CL_HPP_TARGET_OPENCL_VERSION >= 120
5012*6fee86a4SJeremy Kemp         useCreateImage = true;
5013*6fee86a4SJeremy Kemp #else
5014*6fee86a4SJeremy Kemp         useCreateImage = false;
5015*6fee86a4SJeremy Kemp #endif
5016*6fee86a4SJeremy Kemp 
5017*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 120
5018*6fee86a4SJeremy Kemp         if (useCreateImage)
5019*6fee86a4SJeremy Kemp         {
5020*6fee86a4SJeremy Kemp             cl_image_desc desc = {};
5021*6fee86a4SJeremy Kemp             desc.image_type = CL_MEM_OBJECT_IMAGE2D;
5022*6fee86a4SJeremy Kemp             desc.image_width = width;
5023*6fee86a4SJeremy Kemp             desc.image_height = height;
5024*6fee86a4SJeremy Kemp             desc.image_row_pitch = row_pitch;
5025*6fee86a4SJeremy Kemp 
5026*6fee86a4SJeremy Kemp             object_ = ::clCreateImage(
5027*6fee86a4SJeremy Kemp                 context(),
5028*6fee86a4SJeremy Kemp                 flags,
5029*6fee86a4SJeremy Kemp                 &format,
5030*6fee86a4SJeremy Kemp                 &desc,
5031*6fee86a4SJeremy Kemp                 host_ptr,
5032*6fee86a4SJeremy Kemp                 &error);
5033*6fee86a4SJeremy Kemp 
5034*6fee86a4SJeremy Kemp             detail::errHandler(error, __CREATE_IMAGE_ERR);
5035*6fee86a4SJeremy Kemp             if (err != nullptr) {
5036*6fee86a4SJeremy Kemp                 *err = error;
5037*6fee86a4SJeremy Kemp             }
5038*6fee86a4SJeremy Kemp         }
5039*6fee86a4SJeremy Kemp #endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
5040*6fee86a4SJeremy Kemp #if CL_HPP_MINIMUM_OPENCL_VERSION < 120
5041*6fee86a4SJeremy Kemp         if (!useCreateImage)
5042*6fee86a4SJeremy Kemp         {
5043*6fee86a4SJeremy Kemp             object_ = ::clCreateImage2D(
5044*6fee86a4SJeremy Kemp                 context(), flags,&format, width, height, row_pitch, host_ptr, &error);
5045*6fee86a4SJeremy Kemp 
5046*6fee86a4SJeremy Kemp             detail::errHandler(error, __CREATE_IMAGE2D_ERR);
5047*6fee86a4SJeremy Kemp             if (err != nullptr) {
5048*6fee86a4SJeremy Kemp                 *err = error;
5049*6fee86a4SJeremy Kemp             }
5050*6fee86a4SJeremy Kemp         }
5051*6fee86a4SJeremy Kemp #endif // CL_HPP_MINIMUM_OPENCL_VERSION < 120
5052*6fee86a4SJeremy Kemp     }
5053*6fee86a4SJeremy Kemp 
5054*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 120
5055*6fee86a4SJeremy Kemp     /*! \brief Constructs a 2D Image from a buffer.
5056*6fee86a4SJeremy Kemp     * \note This will share storage with the underlying buffer.
5057*6fee86a4SJeremy Kemp     *
5058*6fee86a4SJeremy Kemp     *  Requires OpenCL 2.0 or newer or OpenCL 1.2 and the
5059*6fee86a4SJeremy Kemp     *  cl_khr_image2d_from_buffer extension.
5060*6fee86a4SJeremy Kemp     *
5061*6fee86a4SJeremy Kemp     *  Wraps clCreateImage().
5062*6fee86a4SJeremy Kemp     */
Image2D(const Context & context,ImageFormat format,const Buffer & sourceBuffer,size_type width,size_type height,size_type row_pitch=0,cl_int * err=nullptr)5063*6fee86a4SJeremy Kemp     Image2D(
5064*6fee86a4SJeremy Kemp         const Context& context,
5065*6fee86a4SJeremy Kemp         ImageFormat format,
5066*6fee86a4SJeremy Kemp         const Buffer &sourceBuffer,
5067*6fee86a4SJeremy Kemp         size_type width,
5068*6fee86a4SJeremy Kemp         size_type height,
5069*6fee86a4SJeremy Kemp         size_type row_pitch = 0,
5070*6fee86a4SJeremy Kemp         cl_int* err = nullptr)
5071*6fee86a4SJeremy Kemp     {
5072*6fee86a4SJeremy Kemp         cl_int error;
5073*6fee86a4SJeremy Kemp 
5074*6fee86a4SJeremy Kemp         cl_image_desc desc = {};
5075*6fee86a4SJeremy Kemp         desc.image_type = CL_MEM_OBJECT_IMAGE2D;
5076*6fee86a4SJeremy Kemp         desc.image_width = width;
5077*6fee86a4SJeremy Kemp         desc.image_height = height;
5078*6fee86a4SJeremy Kemp         desc.image_row_pitch = row_pitch;
5079*6fee86a4SJeremy Kemp         desc.buffer = sourceBuffer();
5080*6fee86a4SJeremy Kemp 
5081*6fee86a4SJeremy Kemp         object_ = ::clCreateImage(
5082*6fee86a4SJeremy Kemp             context(),
5083*6fee86a4SJeremy Kemp             0, // flags inherited from buffer
5084*6fee86a4SJeremy Kemp             &format,
5085*6fee86a4SJeremy Kemp             &desc,
5086*6fee86a4SJeremy Kemp             nullptr,
5087*6fee86a4SJeremy Kemp             &error);
5088*6fee86a4SJeremy Kemp 
5089*6fee86a4SJeremy Kemp         detail::errHandler(error, __CREATE_IMAGE_ERR);
5090*6fee86a4SJeremy Kemp         if (err != nullptr) {
5091*6fee86a4SJeremy Kemp             *err = error;
5092*6fee86a4SJeremy Kemp         }
5093*6fee86a4SJeremy Kemp     }
5094*6fee86a4SJeremy Kemp #endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
5095*6fee86a4SJeremy Kemp 
5096*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 200
5097*6fee86a4SJeremy Kemp     /*! \brief Constructs a 2D Image from an image.
5098*6fee86a4SJeremy Kemp     * \note This will share storage with the underlying image but may
5099*6fee86a4SJeremy Kemp     *       reinterpret the channel order and type.
5100*6fee86a4SJeremy Kemp     *
5101*6fee86a4SJeremy Kemp     * The image will be created matching with a descriptor matching the source.
5102*6fee86a4SJeremy Kemp     *
5103*6fee86a4SJeremy Kemp     * \param order is the channel order to reinterpret the image data as.
5104*6fee86a4SJeremy Kemp     *              The channel order may differ as described in the OpenCL
5105*6fee86a4SJeremy Kemp     *              2.0 API specification.
5106*6fee86a4SJeremy Kemp     *
5107*6fee86a4SJeremy Kemp     * Wraps clCreateImage().
5108*6fee86a4SJeremy Kemp     */
Image2D(const Context & context,cl_channel_order order,const Image & sourceImage,cl_int * err=nullptr)5109*6fee86a4SJeremy Kemp     Image2D(
5110*6fee86a4SJeremy Kemp         const Context& context,
5111*6fee86a4SJeremy Kemp         cl_channel_order order,
5112*6fee86a4SJeremy Kemp         const Image &sourceImage,
5113*6fee86a4SJeremy Kemp         cl_int* err = nullptr)
5114*6fee86a4SJeremy Kemp     {
5115*6fee86a4SJeremy Kemp         cl_int error;
5116*6fee86a4SJeremy Kemp 
5117*6fee86a4SJeremy Kemp         // Descriptor fields have to match source image
5118*6fee86a4SJeremy Kemp         size_type sourceWidth =
5119*6fee86a4SJeremy Kemp             sourceImage.getImageInfo<CL_IMAGE_WIDTH>();
5120*6fee86a4SJeremy Kemp         size_type sourceHeight =
5121*6fee86a4SJeremy Kemp             sourceImage.getImageInfo<CL_IMAGE_HEIGHT>();
5122*6fee86a4SJeremy Kemp         size_type sourceRowPitch =
5123*6fee86a4SJeremy Kemp             sourceImage.getImageInfo<CL_IMAGE_ROW_PITCH>();
5124*6fee86a4SJeremy Kemp         cl_uint sourceNumMIPLevels =
5125*6fee86a4SJeremy Kemp             sourceImage.getImageInfo<CL_IMAGE_NUM_MIP_LEVELS>();
5126*6fee86a4SJeremy Kemp         cl_uint sourceNumSamples =
5127*6fee86a4SJeremy Kemp             sourceImage.getImageInfo<CL_IMAGE_NUM_SAMPLES>();
5128*6fee86a4SJeremy Kemp         cl_image_format sourceFormat =
5129*6fee86a4SJeremy Kemp             sourceImage.getImageInfo<CL_IMAGE_FORMAT>();
5130*6fee86a4SJeremy Kemp 
5131*6fee86a4SJeremy Kemp         // Update only the channel order.
5132*6fee86a4SJeremy Kemp         // Channel format inherited from source.
5133*6fee86a4SJeremy Kemp         sourceFormat.image_channel_order = order;
5134*6fee86a4SJeremy Kemp 
5135*6fee86a4SJeremy Kemp         cl_image_desc desc = {};
5136*6fee86a4SJeremy Kemp         desc.image_type = CL_MEM_OBJECT_IMAGE2D;
5137*6fee86a4SJeremy Kemp         desc.image_width = sourceWidth;
5138*6fee86a4SJeremy Kemp         desc.image_height = sourceHeight;
5139*6fee86a4SJeremy Kemp         desc.image_row_pitch = sourceRowPitch;
5140*6fee86a4SJeremy Kemp         desc.num_mip_levels = sourceNumMIPLevels;
5141*6fee86a4SJeremy Kemp         desc.num_samples = sourceNumSamples;
5142*6fee86a4SJeremy Kemp         desc.buffer = sourceImage();
5143*6fee86a4SJeremy Kemp 
5144*6fee86a4SJeremy Kemp         object_ = ::clCreateImage(
5145*6fee86a4SJeremy Kemp             context(),
5146*6fee86a4SJeremy Kemp             0, // flags should be inherited from mem_object
5147*6fee86a4SJeremy Kemp             &sourceFormat,
5148*6fee86a4SJeremy Kemp             &desc,
5149*6fee86a4SJeremy Kemp             nullptr,
5150*6fee86a4SJeremy Kemp             &error);
5151*6fee86a4SJeremy Kemp 
5152*6fee86a4SJeremy Kemp         detail::errHandler(error, __CREATE_IMAGE_ERR);
5153*6fee86a4SJeremy Kemp         if (err != nullptr) {
5154*6fee86a4SJeremy Kemp             *err = error;
5155*6fee86a4SJeremy Kemp         }
5156*6fee86a4SJeremy Kemp     }
5157*6fee86a4SJeremy Kemp #endif //#if CL_HPP_TARGET_OPENCL_VERSION >= 200
5158*6fee86a4SJeremy Kemp 
5159*6fee86a4SJeremy Kemp     //! \brief Default constructor - initializes to nullptr.
Image2D()5160*6fee86a4SJeremy Kemp     Image2D() { }
5161*6fee86a4SJeremy Kemp 
5162*6fee86a4SJeremy Kemp     /*! \brief Constructor from cl_mem - takes ownership.
5163*6fee86a4SJeremy Kemp      *
5164*6fee86a4SJeremy Kemp      * \param retainObject will cause the constructor to retain its cl object.
5165*6fee86a4SJeremy Kemp      *                     Defaults to false to maintain compatibility with
5166*6fee86a4SJeremy Kemp      *                     earlier versions.
5167*6fee86a4SJeremy Kemp      *  See Memory for further details.
5168*6fee86a4SJeremy Kemp      */
Image2D(const cl_mem & image2D,bool retainObject=false)5169*6fee86a4SJeremy Kemp     explicit Image2D(const cl_mem& image2D, bool retainObject = false) :
5170*6fee86a4SJeremy Kemp         Image(image2D, retainObject) { }
5171*6fee86a4SJeremy Kemp 
5172*6fee86a4SJeremy Kemp     /*! \brief Assignment from cl_mem - performs shallow copy.
5173*6fee86a4SJeremy Kemp      *
5174*6fee86a4SJeremy Kemp      *  See Memory for further details.
5175*6fee86a4SJeremy Kemp      */
operator =(const cl_mem & rhs)5176*6fee86a4SJeremy Kemp     Image2D& operator = (const cl_mem& rhs)
5177*6fee86a4SJeremy Kemp     {
5178*6fee86a4SJeremy Kemp         Image::operator=(rhs);
5179*6fee86a4SJeremy Kemp         return *this;
5180*6fee86a4SJeremy Kemp     }
5181*6fee86a4SJeremy Kemp 
5182*6fee86a4SJeremy Kemp 
5183*6fee86a4SJeremy Kemp 
5184*6fee86a4SJeremy Kemp 
5185*6fee86a4SJeremy Kemp };
5186*6fee86a4SJeremy Kemp 
5187*6fee86a4SJeremy Kemp 
5188*6fee86a4SJeremy Kemp #if defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS)
5189*6fee86a4SJeremy Kemp /*! \brief Class interface for GL 2D Image Memory objects.
5190*6fee86a4SJeremy Kemp  *
5191*6fee86a4SJeremy Kemp  *  This is provided to facilitate interoperability with OpenGL.
5192*6fee86a4SJeremy Kemp  *
5193*6fee86a4SJeremy Kemp  *  See Memory for details about copy semantics, etc.
5194*6fee86a4SJeremy Kemp  *
5195*6fee86a4SJeremy Kemp  *  \see Memory
5196*6fee86a4SJeremy Kemp  *  \note Deprecated for OpenCL 1.2. Please use ImageGL instead.
5197*6fee86a4SJeremy Kemp  */
5198*6fee86a4SJeremy Kemp class CL_API_PREFIX__VERSION_1_1_DEPRECATED Image2DGL : public Image2D
5199*6fee86a4SJeremy Kemp {
5200*6fee86a4SJeremy Kemp public:
5201*6fee86a4SJeremy Kemp     /*! \brief Constructs an Image2DGL in a specified context, from a given
5202*6fee86a4SJeremy Kemp      *         GL Texture.
5203*6fee86a4SJeremy Kemp      *
5204*6fee86a4SJeremy Kemp      *  Wraps clCreateFromGLTexture2D().
5205*6fee86a4SJeremy Kemp      */
Image2DGL(const Context & context,cl_mem_flags flags,cl_GLenum target,cl_GLint miplevel,cl_GLuint texobj,cl_int * err=nullptr)5206*6fee86a4SJeremy Kemp     Image2DGL(
5207*6fee86a4SJeremy Kemp         const Context& context,
5208*6fee86a4SJeremy Kemp         cl_mem_flags flags,
5209*6fee86a4SJeremy Kemp         cl_GLenum target,
5210*6fee86a4SJeremy Kemp         cl_GLint  miplevel,
5211*6fee86a4SJeremy Kemp         cl_GLuint texobj,
5212*6fee86a4SJeremy Kemp         cl_int * err = nullptr)
5213*6fee86a4SJeremy Kemp     {
5214*6fee86a4SJeremy Kemp         cl_int error;
5215*6fee86a4SJeremy Kemp         object_ = ::clCreateFromGLTexture2D(
5216*6fee86a4SJeremy Kemp             context(),
5217*6fee86a4SJeremy Kemp             flags,
5218*6fee86a4SJeremy Kemp             target,
5219*6fee86a4SJeremy Kemp             miplevel,
5220*6fee86a4SJeremy Kemp             texobj,
5221*6fee86a4SJeremy Kemp             &error);
5222*6fee86a4SJeremy Kemp 
5223*6fee86a4SJeremy Kemp         detail::errHandler(error, __CREATE_GL_TEXTURE_2D_ERR);
5224*6fee86a4SJeremy Kemp         if (err != nullptr) {
5225*6fee86a4SJeremy Kemp             *err = error;
5226*6fee86a4SJeremy Kemp         }
5227*6fee86a4SJeremy Kemp 
5228*6fee86a4SJeremy Kemp     }
5229*6fee86a4SJeremy Kemp 
5230*6fee86a4SJeremy Kemp     //! \brief Default constructor - initializes to nullptr.
Image2DGL()5231*6fee86a4SJeremy Kemp     Image2DGL() : Image2D() { }
5232*6fee86a4SJeremy Kemp 
5233*6fee86a4SJeremy Kemp     /*! \brief Constructor from cl_mem - takes ownership.
5234*6fee86a4SJeremy Kemp      *
5235*6fee86a4SJeremy Kemp      * \param retainObject will cause the constructor to retain its cl object.
5236*6fee86a4SJeremy Kemp      *                     Defaults to false to maintain compatibility with
5237*6fee86a4SJeremy Kemp      *                     earlier versions.
5238*6fee86a4SJeremy Kemp      *  See Memory for further details.
5239*6fee86a4SJeremy Kemp      */
Image2DGL(const cl_mem & image,bool retainObject=false)5240*6fee86a4SJeremy Kemp     explicit Image2DGL(const cl_mem& image, bool retainObject = false) :
5241*6fee86a4SJeremy Kemp         Image2D(image, retainObject) { }
5242*6fee86a4SJeremy Kemp 
5243*6fee86a4SJeremy Kemp     /*! \brief Assignment from cl_mem - performs shallow copy.
5244*6fee86a4SJeremy Kemp      *c
5245*6fee86a4SJeremy Kemp      *  See Memory for further details.
5246*6fee86a4SJeremy Kemp      */
operator =(const cl_mem & rhs)5247*6fee86a4SJeremy Kemp     Image2DGL& operator = (const cl_mem& rhs)
5248*6fee86a4SJeremy Kemp     {
5249*6fee86a4SJeremy Kemp         Image2D::operator=(rhs);
5250*6fee86a4SJeremy Kemp         return *this;
5251*6fee86a4SJeremy Kemp     }
5252*6fee86a4SJeremy Kemp 
5253*6fee86a4SJeremy Kemp 
5254*6fee86a4SJeremy Kemp 
5255*6fee86a4SJeremy Kemp } CL_API_SUFFIX__VERSION_1_1_DEPRECATED;
5256*6fee86a4SJeremy Kemp #endif // CL_USE_DEPRECATED_OPENCL_1_1_APIS
5257*6fee86a4SJeremy Kemp 
5258*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 120
5259*6fee86a4SJeremy Kemp /*! \class Image2DArray
5260*6fee86a4SJeremy Kemp  * \brief Image interface for arrays of 2D images.
5261*6fee86a4SJeremy Kemp  */
5262*6fee86a4SJeremy Kemp class Image2DArray : public Image
5263*6fee86a4SJeremy Kemp {
5264*6fee86a4SJeremy Kemp public:
Image2DArray(const Context & context,cl_mem_flags flags,ImageFormat format,size_type arraySize,size_type width,size_type height,size_type rowPitch,size_type slicePitch,void * host_ptr=nullptr,cl_int * err=nullptr)5265*6fee86a4SJeremy Kemp     Image2DArray(
5266*6fee86a4SJeremy Kemp         const Context& context,
5267*6fee86a4SJeremy Kemp         cl_mem_flags flags,
5268*6fee86a4SJeremy Kemp         ImageFormat format,
5269*6fee86a4SJeremy Kemp         size_type arraySize,
5270*6fee86a4SJeremy Kemp         size_type width,
5271*6fee86a4SJeremy Kemp         size_type height,
5272*6fee86a4SJeremy Kemp         size_type rowPitch,
5273*6fee86a4SJeremy Kemp         size_type slicePitch,
5274*6fee86a4SJeremy Kemp         void* host_ptr = nullptr,
5275*6fee86a4SJeremy Kemp         cl_int* err = nullptr)
5276*6fee86a4SJeremy Kemp     {
5277*6fee86a4SJeremy Kemp         cl_int error;
5278*6fee86a4SJeremy Kemp 
5279*6fee86a4SJeremy Kemp         cl_image_desc desc = {};
5280*6fee86a4SJeremy Kemp         desc.image_type = CL_MEM_OBJECT_IMAGE2D_ARRAY;
5281*6fee86a4SJeremy Kemp         desc.image_width = width;
5282*6fee86a4SJeremy Kemp         desc.image_height = height;
5283*6fee86a4SJeremy Kemp         desc.image_array_size = arraySize;
5284*6fee86a4SJeremy Kemp         desc.image_row_pitch = rowPitch;
5285*6fee86a4SJeremy Kemp         desc.image_slice_pitch = slicePitch;
5286*6fee86a4SJeremy Kemp 
5287*6fee86a4SJeremy Kemp         object_ = ::clCreateImage(
5288*6fee86a4SJeremy Kemp             context(),
5289*6fee86a4SJeremy Kemp             flags,
5290*6fee86a4SJeremy Kemp             &format,
5291*6fee86a4SJeremy Kemp             &desc,
5292*6fee86a4SJeremy Kemp             host_ptr,
5293*6fee86a4SJeremy Kemp             &error);
5294*6fee86a4SJeremy Kemp 
5295*6fee86a4SJeremy Kemp         detail::errHandler(error, __CREATE_IMAGE_ERR);
5296*6fee86a4SJeremy Kemp         if (err != nullptr) {
5297*6fee86a4SJeremy Kemp             *err = error;
5298*6fee86a4SJeremy Kemp         }
5299*6fee86a4SJeremy Kemp     }
5300*6fee86a4SJeremy Kemp 
Image2DArray()5301*6fee86a4SJeremy Kemp     Image2DArray() { }
5302*6fee86a4SJeremy Kemp 
5303*6fee86a4SJeremy Kemp     /*! \brief Constructor from cl_mem - takes ownership.
5304*6fee86a4SJeremy Kemp      *
5305*6fee86a4SJeremy Kemp      * \param retainObject will cause the constructor to retain its cl object.
5306*6fee86a4SJeremy Kemp      *                     Defaults to false to maintain compatibility with
5307*6fee86a4SJeremy Kemp      *                     earlier versions.
5308*6fee86a4SJeremy Kemp      *  See Memory for further details.
5309*6fee86a4SJeremy Kemp      */
Image2DArray(const cl_mem & imageArray,bool retainObject=false)5310*6fee86a4SJeremy Kemp     explicit Image2DArray(const cl_mem& imageArray, bool retainObject = false) : Image(imageArray, retainObject) { }
5311*6fee86a4SJeremy Kemp 
operator =(const cl_mem & rhs)5312*6fee86a4SJeremy Kemp     Image2DArray& operator = (const cl_mem& rhs)
5313*6fee86a4SJeremy Kemp     {
5314*6fee86a4SJeremy Kemp         Image::operator=(rhs);
5315*6fee86a4SJeremy Kemp         return *this;
5316*6fee86a4SJeremy Kemp     }
5317*6fee86a4SJeremy Kemp 
5318*6fee86a4SJeremy Kemp };
5319*6fee86a4SJeremy Kemp #endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 120
5320*6fee86a4SJeremy Kemp 
5321*6fee86a4SJeremy Kemp /*! \brief Class interface for 3D Image Memory objects.
5322*6fee86a4SJeremy Kemp  *
5323*6fee86a4SJeremy Kemp  *  See Memory for details about copy semantics, etc.
5324*6fee86a4SJeremy Kemp  *
5325*6fee86a4SJeremy Kemp  *  \see Memory
5326*6fee86a4SJeremy Kemp  */
5327*6fee86a4SJeremy Kemp class Image3D : public Image
5328*6fee86a4SJeremy Kemp {
5329*6fee86a4SJeremy Kemp public:
5330*6fee86a4SJeremy Kemp     /*! \brief Constructs a 3D Image in a specified context.
5331*6fee86a4SJeremy Kemp      *
5332*6fee86a4SJeremy Kemp      *  Wraps clCreateImage().
5333*6fee86a4SJeremy Kemp      */
Image3D(const Context & context,cl_mem_flags flags,ImageFormat format,size_type width,size_type height,size_type depth,size_type row_pitch=0,size_type slice_pitch=0,void * host_ptr=nullptr,cl_int * err=nullptr)5334*6fee86a4SJeremy Kemp     Image3D(
5335*6fee86a4SJeremy Kemp         const Context& context,
5336*6fee86a4SJeremy Kemp         cl_mem_flags flags,
5337*6fee86a4SJeremy Kemp         ImageFormat format,
5338*6fee86a4SJeremy Kemp         size_type width,
5339*6fee86a4SJeremy Kemp         size_type height,
5340*6fee86a4SJeremy Kemp         size_type depth,
5341*6fee86a4SJeremy Kemp         size_type row_pitch = 0,
5342*6fee86a4SJeremy Kemp         size_type slice_pitch = 0,
5343*6fee86a4SJeremy Kemp         void* host_ptr = nullptr,
5344*6fee86a4SJeremy Kemp         cl_int* err = nullptr)
5345*6fee86a4SJeremy Kemp     {
5346*6fee86a4SJeremy Kemp         cl_int error;
5347*6fee86a4SJeremy Kemp         bool useCreateImage;
5348*6fee86a4SJeremy Kemp 
5349*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 120 && CL_HPP_MINIMUM_OPENCL_VERSION < 120
5350*6fee86a4SJeremy Kemp         // Run-time decision based on the actual platform
5351*6fee86a4SJeremy Kemp         {
5352*6fee86a4SJeremy Kemp             cl_uint version = detail::getContextPlatformVersion(context());
5353*6fee86a4SJeremy Kemp             useCreateImage = (version >= 0x10002); // OpenCL 1.2 or above
5354*6fee86a4SJeremy Kemp         }
5355*6fee86a4SJeremy Kemp #elif CL_HPP_TARGET_OPENCL_VERSION >= 120
5356*6fee86a4SJeremy Kemp         useCreateImage = true;
5357*6fee86a4SJeremy Kemp #else
5358*6fee86a4SJeremy Kemp         useCreateImage = false;
5359*6fee86a4SJeremy Kemp #endif
5360*6fee86a4SJeremy Kemp 
5361*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 120
5362*6fee86a4SJeremy Kemp         if (useCreateImage)
5363*6fee86a4SJeremy Kemp         {
5364*6fee86a4SJeremy Kemp             cl_image_desc desc = {};
5365*6fee86a4SJeremy Kemp             desc.image_type = CL_MEM_OBJECT_IMAGE3D;
5366*6fee86a4SJeremy Kemp             desc.image_width = width;
5367*6fee86a4SJeremy Kemp             desc.image_height = height;
5368*6fee86a4SJeremy Kemp             desc.image_depth = depth;
5369*6fee86a4SJeremy Kemp             desc.image_row_pitch = row_pitch;
5370*6fee86a4SJeremy Kemp             desc.image_slice_pitch = slice_pitch;
5371*6fee86a4SJeremy Kemp 
5372*6fee86a4SJeremy Kemp             object_ = ::clCreateImage(
5373*6fee86a4SJeremy Kemp                 context(),
5374*6fee86a4SJeremy Kemp                 flags,
5375*6fee86a4SJeremy Kemp                 &format,
5376*6fee86a4SJeremy Kemp                 &desc,
5377*6fee86a4SJeremy Kemp                 host_ptr,
5378*6fee86a4SJeremy Kemp                 &error);
5379*6fee86a4SJeremy Kemp 
5380*6fee86a4SJeremy Kemp             detail::errHandler(error, __CREATE_IMAGE_ERR);
5381*6fee86a4SJeremy Kemp             if (err != nullptr) {
5382*6fee86a4SJeremy Kemp                 *err = error;
5383*6fee86a4SJeremy Kemp             }
5384*6fee86a4SJeremy Kemp         }
5385*6fee86a4SJeremy Kemp #endif  // CL_HPP_TARGET_OPENCL_VERSION >= 120
5386*6fee86a4SJeremy Kemp #if CL_HPP_MINIMUM_OPENCL_VERSION < 120
5387*6fee86a4SJeremy Kemp         if (!useCreateImage)
5388*6fee86a4SJeremy Kemp         {
5389*6fee86a4SJeremy Kemp             object_ = ::clCreateImage3D(
5390*6fee86a4SJeremy Kemp                 context(), flags, &format, width, height, depth, row_pitch,
5391*6fee86a4SJeremy Kemp                 slice_pitch, host_ptr, &error);
5392*6fee86a4SJeremy Kemp 
5393*6fee86a4SJeremy Kemp             detail::errHandler(error, __CREATE_IMAGE3D_ERR);
5394*6fee86a4SJeremy Kemp             if (err != nullptr) {
5395*6fee86a4SJeremy Kemp                 *err = error;
5396*6fee86a4SJeremy Kemp             }
5397*6fee86a4SJeremy Kemp         }
5398*6fee86a4SJeremy Kemp #endif // CL_HPP_MINIMUM_OPENCL_VERSION < 120
5399*6fee86a4SJeremy Kemp     }
5400*6fee86a4SJeremy Kemp 
5401*6fee86a4SJeremy Kemp     //! \brief Default constructor - initializes to nullptr.
Image3D()5402*6fee86a4SJeremy Kemp     Image3D() : Image() { }
5403*6fee86a4SJeremy Kemp 
5404*6fee86a4SJeremy Kemp     /*! \brief Constructor from cl_mem - takes ownership.
5405*6fee86a4SJeremy Kemp      *
5406*6fee86a4SJeremy Kemp      * \param retainObject will cause the constructor to retain its cl object.
5407*6fee86a4SJeremy Kemp      *                     Defaults to false to maintain compatibility with
5408*6fee86a4SJeremy Kemp      *                     earlier versions.
5409*6fee86a4SJeremy Kemp      *  See Memory for further details.
5410*6fee86a4SJeremy Kemp      */
Image3D(const cl_mem & image3D,bool retainObject=false)5411*6fee86a4SJeremy Kemp     explicit Image3D(const cl_mem& image3D, bool retainObject = false) :
5412*6fee86a4SJeremy Kemp         Image(image3D, retainObject) { }
5413*6fee86a4SJeremy Kemp 
5414*6fee86a4SJeremy Kemp     /*! \brief Assignment from cl_mem - performs shallow copy.
5415*6fee86a4SJeremy Kemp      *
5416*6fee86a4SJeremy Kemp      *  See Memory for further details.
5417*6fee86a4SJeremy Kemp      */
operator =(const cl_mem & rhs)5418*6fee86a4SJeremy Kemp     Image3D& operator = (const cl_mem& rhs)
5419*6fee86a4SJeremy Kemp     {
5420*6fee86a4SJeremy Kemp         Image::operator=(rhs);
5421*6fee86a4SJeremy Kemp         return *this;
5422*6fee86a4SJeremy Kemp     }
5423*6fee86a4SJeremy Kemp 
5424*6fee86a4SJeremy Kemp };
5425*6fee86a4SJeremy Kemp 
5426*6fee86a4SJeremy Kemp #if defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS)
5427*6fee86a4SJeremy Kemp /*! \brief Class interface for GL 3D Image Memory objects.
5428*6fee86a4SJeremy Kemp  *
5429*6fee86a4SJeremy Kemp  *  This is provided to facilitate interoperability with OpenGL.
5430*6fee86a4SJeremy Kemp  *
5431*6fee86a4SJeremy Kemp  *  See Memory for details about copy semantics, etc.
5432*6fee86a4SJeremy Kemp  *
5433*6fee86a4SJeremy Kemp  *  \see Memory
5434*6fee86a4SJeremy Kemp  */
5435*6fee86a4SJeremy Kemp class Image3DGL : public Image3D
5436*6fee86a4SJeremy Kemp {
5437*6fee86a4SJeremy Kemp public:
5438*6fee86a4SJeremy Kemp     /*! \brief Constructs an Image3DGL in a specified context, from a given
5439*6fee86a4SJeremy Kemp      *         GL Texture.
5440*6fee86a4SJeremy Kemp      *
5441*6fee86a4SJeremy Kemp      *  Wraps clCreateFromGLTexture3D().
5442*6fee86a4SJeremy Kemp      */
Image3DGL(const Context & context,cl_mem_flags flags,cl_GLenum target,cl_GLint miplevel,cl_GLuint texobj,cl_int * err=nullptr)5443*6fee86a4SJeremy Kemp     Image3DGL(
5444*6fee86a4SJeremy Kemp         const Context& context,
5445*6fee86a4SJeremy Kemp         cl_mem_flags flags,
5446*6fee86a4SJeremy Kemp         cl_GLenum target,
5447*6fee86a4SJeremy Kemp         cl_GLint  miplevel,
5448*6fee86a4SJeremy Kemp         cl_GLuint texobj,
5449*6fee86a4SJeremy Kemp         cl_int * err = nullptr)
5450*6fee86a4SJeremy Kemp     {
5451*6fee86a4SJeremy Kemp         cl_int error;
5452*6fee86a4SJeremy Kemp         object_ = ::clCreateFromGLTexture3D(
5453*6fee86a4SJeremy Kemp             context(),
5454*6fee86a4SJeremy Kemp             flags,
5455*6fee86a4SJeremy Kemp             target,
5456*6fee86a4SJeremy Kemp             miplevel,
5457*6fee86a4SJeremy Kemp             texobj,
5458*6fee86a4SJeremy Kemp             &error);
5459*6fee86a4SJeremy Kemp 
5460*6fee86a4SJeremy Kemp         detail::errHandler(error, __CREATE_GL_TEXTURE_3D_ERR);
5461*6fee86a4SJeremy Kemp         if (err != nullptr) {
5462*6fee86a4SJeremy Kemp             *err = error;
5463*6fee86a4SJeremy Kemp         }
5464*6fee86a4SJeremy Kemp     }
5465*6fee86a4SJeremy Kemp 
5466*6fee86a4SJeremy Kemp     //! \brief Default constructor - initializes to nullptr.
Image3DGL()5467*6fee86a4SJeremy Kemp     Image3DGL() : Image3D() { }
5468*6fee86a4SJeremy Kemp 
5469*6fee86a4SJeremy Kemp     /*! \brief Constructor from cl_mem - takes ownership.
5470*6fee86a4SJeremy Kemp      *
5471*6fee86a4SJeremy Kemp      * \param retainObject will cause the constructor to retain its cl object.
5472*6fee86a4SJeremy Kemp      *                     Defaults to false to maintain compatibility with
5473*6fee86a4SJeremy Kemp      *                     earlier versions.
5474*6fee86a4SJeremy Kemp      *  See Memory for further details.
5475*6fee86a4SJeremy Kemp      */
Image3DGL(const cl_mem & image,bool retainObject=false)5476*6fee86a4SJeremy Kemp     explicit Image3DGL(const cl_mem& image, bool retainObject = false) :
5477*6fee86a4SJeremy Kemp         Image3D(image, retainObject) { }
5478*6fee86a4SJeremy Kemp 
5479*6fee86a4SJeremy Kemp     /*! \brief Assignment from cl_mem - performs shallow copy.
5480*6fee86a4SJeremy Kemp      *
5481*6fee86a4SJeremy Kemp      *  See Memory for further details.
5482*6fee86a4SJeremy Kemp      */
operator =(const cl_mem & rhs)5483*6fee86a4SJeremy Kemp     Image3DGL& operator = (const cl_mem& rhs)
5484*6fee86a4SJeremy Kemp     {
5485*6fee86a4SJeremy Kemp         Image3D::operator=(rhs);
5486*6fee86a4SJeremy Kemp         return *this;
5487*6fee86a4SJeremy Kemp     }
5488*6fee86a4SJeremy Kemp 
5489*6fee86a4SJeremy Kemp };
5490*6fee86a4SJeremy Kemp #endif // CL_USE_DEPRECATED_OPENCL_1_1_APIS
5491*6fee86a4SJeremy Kemp 
5492*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 120
5493*6fee86a4SJeremy Kemp /*! \class ImageGL
5494*6fee86a4SJeremy Kemp  * \brief general image interface for GL interop.
5495*6fee86a4SJeremy Kemp  * We abstract the 2D and 3D GL images into a single instance here
5496*6fee86a4SJeremy Kemp  * that wraps all GL sourced images on the grounds that setup information
5497*6fee86a4SJeremy Kemp  * was performed by OpenCL anyway.
5498*6fee86a4SJeremy Kemp  */
5499*6fee86a4SJeremy Kemp class ImageGL : public Image
5500*6fee86a4SJeremy Kemp {
5501*6fee86a4SJeremy Kemp public:
ImageGL(const Context & context,cl_mem_flags flags,cl_GLenum target,cl_GLint miplevel,cl_GLuint texobj,cl_int * err=nullptr)5502*6fee86a4SJeremy Kemp     ImageGL(
5503*6fee86a4SJeremy Kemp         const Context& context,
5504*6fee86a4SJeremy Kemp         cl_mem_flags flags,
5505*6fee86a4SJeremy Kemp         cl_GLenum target,
5506*6fee86a4SJeremy Kemp         cl_GLint  miplevel,
5507*6fee86a4SJeremy Kemp         cl_GLuint texobj,
5508*6fee86a4SJeremy Kemp         cl_int * err = nullptr)
5509*6fee86a4SJeremy Kemp     {
5510*6fee86a4SJeremy Kemp         cl_int error;
5511*6fee86a4SJeremy Kemp         object_ = ::clCreateFromGLTexture(
5512*6fee86a4SJeremy Kemp             context(),
5513*6fee86a4SJeremy Kemp             flags,
5514*6fee86a4SJeremy Kemp             target,
5515*6fee86a4SJeremy Kemp             miplevel,
5516*6fee86a4SJeremy Kemp             texobj,
5517*6fee86a4SJeremy Kemp             &error);
5518*6fee86a4SJeremy Kemp 
5519*6fee86a4SJeremy Kemp         detail::errHandler(error, __CREATE_GL_TEXTURE_ERR);
5520*6fee86a4SJeremy Kemp         if (err != nullptr) {
5521*6fee86a4SJeremy Kemp             *err = error;
5522*6fee86a4SJeremy Kemp         }
5523*6fee86a4SJeremy Kemp     }
5524*6fee86a4SJeremy Kemp 
ImageGL()5525*6fee86a4SJeremy Kemp     ImageGL() : Image() { }
5526*6fee86a4SJeremy Kemp 
5527*6fee86a4SJeremy Kemp     /*! \brief Constructor from cl_mem - takes ownership.
5528*6fee86a4SJeremy Kemp      *
5529*6fee86a4SJeremy Kemp      * \param retainObject will cause the constructor to retain its cl object.
5530*6fee86a4SJeremy Kemp      *                     Defaults to false to maintain compatibility with
5531*6fee86a4SJeremy Kemp      *                     earlier versions.
5532*6fee86a4SJeremy Kemp      *  See Memory for further details.
5533*6fee86a4SJeremy Kemp      */
ImageGL(const cl_mem & image,bool retainObject=false)5534*6fee86a4SJeremy Kemp     explicit ImageGL(const cl_mem& image, bool retainObject = false) :
5535*6fee86a4SJeremy Kemp         Image(image, retainObject) { }
5536*6fee86a4SJeremy Kemp 
operator =(const cl_mem & rhs)5537*6fee86a4SJeremy Kemp     ImageGL& operator = (const cl_mem& rhs)
5538*6fee86a4SJeremy Kemp     {
5539*6fee86a4SJeremy Kemp         Image::operator=(rhs);
5540*6fee86a4SJeremy Kemp         return *this;
5541*6fee86a4SJeremy Kemp     }
5542*6fee86a4SJeremy Kemp 
5543*6fee86a4SJeremy Kemp };
5544*6fee86a4SJeremy Kemp #endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
5545*6fee86a4SJeremy Kemp 
5546*6fee86a4SJeremy Kemp 
5547*6fee86a4SJeremy Kemp 
5548*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 200
5549*6fee86a4SJeremy Kemp /*! \brief Class interface for Pipe Memory Objects.
5550*6fee86a4SJeremy Kemp *
5551*6fee86a4SJeremy Kemp *  See Memory for details about copy semantics, etc.
5552*6fee86a4SJeremy Kemp *
5553*6fee86a4SJeremy Kemp *  \see Memory
5554*6fee86a4SJeremy Kemp */
5555*6fee86a4SJeremy Kemp class Pipe : public Memory
5556*6fee86a4SJeremy Kemp {
5557*6fee86a4SJeremy Kemp public:
5558*6fee86a4SJeremy Kemp 
5559*6fee86a4SJeremy Kemp     /*! \brief Constructs a Pipe in a specified context.
5560*6fee86a4SJeremy Kemp      *
5561*6fee86a4SJeremy Kemp      * Wraps clCreatePipe().
5562*6fee86a4SJeremy Kemp      * @param context Context in which to create the pipe.
5563*6fee86a4SJeremy Kemp      * @param flags Bitfield. Only CL_MEM_READ_WRITE and CL_MEM_HOST_NO_ACCESS are valid.
5564*6fee86a4SJeremy Kemp      * @param packet_size Size in bytes of a single packet of the pipe.
5565*6fee86a4SJeremy Kemp      * @param max_packets Number of packets that may be stored in the pipe.
5566*6fee86a4SJeremy Kemp      *
5567*6fee86a4SJeremy Kemp      */
Pipe(const Context & context,cl_uint packet_size,cl_uint max_packets,cl_int * err=nullptr)5568*6fee86a4SJeremy Kemp     Pipe(
5569*6fee86a4SJeremy Kemp         const Context& context,
5570*6fee86a4SJeremy Kemp         cl_uint packet_size,
5571*6fee86a4SJeremy Kemp         cl_uint max_packets,
5572*6fee86a4SJeremy Kemp         cl_int* err = nullptr)
5573*6fee86a4SJeremy Kemp     {
5574*6fee86a4SJeremy Kemp         cl_int error;
5575*6fee86a4SJeremy Kemp 
5576*6fee86a4SJeremy Kemp         cl_mem_flags flags = CL_MEM_READ_WRITE | CL_MEM_HOST_NO_ACCESS;
5577*6fee86a4SJeremy Kemp         object_ = ::clCreatePipe(context(), flags, packet_size, max_packets, nullptr, &error);
5578*6fee86a4SJeremy Kemp 
5579*6fee86a4SJeremy Kemp         detail::errHandler(error, __CREATE_PIPE_ERR);
5580*6fee86a4SJeremy Kemp         if (err != nullptr) {
5581*6fee86a4SJeremy Kemp             *err = error;
5582*6fee86a4SJeremy Kemp         }
5583*6fee86a4SJeremy Kemp     }
5584*6fee86a4SJeremy Kemp 
5585*6fee86a4SJeremy Kemp     /*! \brief Constructs a Pipe in a the default context.
5586*6fee86a4SJeremy Kemp      *
5587*6fee86a4SJeremy Kemp      * Wraps clCreatePipe().
5588*6fee86a4SJeremy Kemp      * @param flags Bitfield. Only CL_MEM_READ_WRITE and CL_MEM_HOST_NO_ACCESS are valid.
5589*6fee86a4SJeremy Kemp      * @param packet_size Size in bytes of a single packet of the pipe.
5590*6fee86a4SJeremy Kemp      * @param max_packets Number of packets that may be stored in the pipe.
5591*6fee86a4SJeremy Kemp      *
5592*6fee86a4SJeremy Kemp      */
Pipe(cl_uint packet_size,cl_uint max_packets,cl_int * err=nullptr)5593*6fee86a4SJeremy Kemp     Pipe(
5594*6fee86a4SJeremy Kemp         cl_uint packet_size,
5595*6fee86a4SJeremy Kemp         cl_uint max_packets,
5596*6fee86a4SJeremy Kemp         cl_int* err = nullptr)
5597*6fee86a4SJeremy Kemp     {
5598*6fee86a4SJeremy Kemp         cl_int error;
5599*6fee86a4SJeremy Kemp 
5600*6fee86a4SJeremy Kemp         Context context = Context::getDefault(err);
5601*6fee86a4SJeremy Kemp 
5602*6fee86a4SJeremy Kemp         cl_mem_flags flags = CL_MEM_READ_WRITE | CL_MEM_HOST_NO_ACCESS;
5603*6fee86a4SJeremy Kemp         object_ = ::clCreatePipe(context(), flags, packet_size, max_packets, nullptr, &error);
5604*6fee86a4SJeremy Kemp 
5605*6fee86a4SJeremy Kemp         detail::errHandler(error, __CREATE_PIPE_ERR);
5606*6fee86a4SJeremy Kemp         if (err != nullptr) {
5607*6fee86a4SJeremy Kemp             *err = error;
5608*6fee86a4SJeremy Kemp         }
5609*6fee86a4SJeremy Kemp     }
5610*6fee86a4SJeremy Kemp 
5611*6fee86a4SJeremy Kemp     //! \brief Default constructor - initializes to nullptr.
Pipe()5612*6fee86a4SJeremy Kemp     Pipe() : Memory() { }
5613*6fee86a4SJeremy Kemp 
5614*6fee86a4SJeremy Kemp     /*! \brief Constructor from cl_mem - takes ownership.
5615*6fee86a4SJeremy Kemp      *
5616*6fee86a4SJeremy Kemp      * \param retainObject will cause the constructor to retain its cl object.
5617*6fee86a4SJeremy Kemp      *                     Defaults to false to maintain compatibility with earlier versions.
5618*6fee86a4SJeremy Kemp      *
5619*6fee86a4SJeremy Kemp      *  See Memory for further details.
5620*6fee86a4SJeremy Kemp      */
Pipe(const cl_mem & pipe,bool retainObject=false)5621*6fee86a4SJeremy Kemp     explicit Pipe(const cl_mem& pipe, bool retainObject = false) :
5622*6fee86a4SJeremy Kemp         Memory(pipe, retainObject) { }
5623*6fee86a4SJeremy Kemp 
5624*6fee86a4SJeremy Kemp     /*! \brief Assignment from cl_mem - performs shallow copy.
5625*6fee86a4SJeremy Kemp      *
5626*6fee86a4SJeremy Kemp      *  See Memory for further details.
5627*6fee86a4SJeremy Kemp      */
operator =(const cl_mem & rhs)5628*6fee86a4SJeremy Kemp     Pipe& operator = (const cl_mem& rhs)
5629*6fee86a4SJeremy Kemp     {
5630*6fee86a4SJeremy Kemp         Memory::operator=(rhs);
5631*6fee86a4SJeremy Kemp         return *this;
5632*6fee86a4SJeremy Kemp     }
5633*6fee86a4SJeremy Kemp 
5634*6fee86a4SJeremy Kemp 
5635*6fee86a4SJeremy Kemp 
5636*6fee86a4SJeremy Kemp     //! \brief Wrapper for clGetMemObjectInfo().
5637*6fee86a4SJeremy Kemp     template <typename T>
getInfo(cl_pipe_info name,T * param) const5638*6fee86a4SJeremy Kemp     cl_int getInfo(cl_pipe_info name, T* param) const
5639*6fee86a4SJeremy Kemp     {
5640*6fee86a4SJeremy Kemp         return detail::errHandler(
5641*6fee86a4SJeremy Kemp             detail::getInfo(&::clGetPipeInfo, object_, name, param),
5642*6fee86a4SJeremy Kemp             __GET_PIPE_INFO_ERR);
5643*6fee86a4SJeremy Kemp     }
5644*6fee86a4SJeremy Kemp 
5645*6fee86a4SJeremy Kemp     //! \brief Wrapper for clGetMemObjectInfo() that returns by value.
5646*6fee86a4SJeremy Kemp     template <cl_pipe_info name> typename
5647*6fee86a4SJeremy Kemp         detail::param_traits<detail::cl_pipe_info, name>::param_type
getInfo(cl_int * err=nullptr) const5648*6fee86a4SJeremy Kemp         getInfo(cl_int* err = nullptr) const
5649*6fee86a4SJeremy Kemp     {
5650*6fee86a4SJeremy Kemp         typename detail::param_traits<
5651*6fee86a4SJeremy Kemp             detail::cl_pipe_info, name>::param_type param;
5652*6fee86a4SJeremy Kemp         cl_int result = getInfo(name, &param);
5653*6fee86a4SJeremy Kemp         if (err != nullptr) {
5654*6fee86a4SJeremy Kemp             *err = result;
5655*6fee86a4SJeremy Kemp         }
5656*6fee86a4SJeremy Kemp         return param;
5657*6fee86a4SJeremy Kemp     }
5658*6fee86a4SJeremy Kemp }; // class Pipe
5659*6fee86a4SJeremy Kemp #endif // CL_HPP_TARGET_OPENCL_VERSION >= 200
5660*6fee86a4SJeremy Kemp 
5661*6fee86a4SJeremy Kemp 
5662*6fee86a4SJeremy Kemp /*! \brief Class interface for cl_sampler.
5663*6fee86a4SJeremy Kemp  *
5664*6fee86a4SJeremy Kemp  *  \note Copies of these objects are shallow, meaning that the copy will refer
5665*6fee86a4SJeremy Kemp  *        to the same underlying cl_sampler as the original.  For details, see
5666*6fee86a4SJeremy Kemp  *        clRetainSampler() and clReleaseSampler().
5667*6fee86a4SJeremy Kemp  *
5668*6fee86a4SJeremy Kemp  *  \see cl_sampler
5669*6fee86a4SJeremy Kemp  */
5670*6fee86a4SJeremy Kemp class Sampler : public detail::Wrapper<cl_sampler>
5671*6fee86a4SJeremy Kemp {
5672*6fee86a4SJeremy Kemp public:
5673*6fee86a4SJeremy Kemp     //! \brief Default constructor - initializes to nullptr.
Sampler()5674*6fee86a4SJeremy Kemp     Sampler() { }
5675*6fee86a4SJeremy Kemp 
5676*6fee86a4SJeremy Kemp     /*! \brief Constructs a Sampler in a specified context.
5677*6fee86a4SJeremy Kemp      *
5678*6fee86a4SJeremy Kemp      *  Wraps clCreateSampler().
5679*6fee86a4SJeremy Kemp      */
Sampler(const Context & context,cl_bool normalized_coords,cl_addressing_mode addressing_mode,cl_filter_mode filter_mode,cl_int * err=nullptr)5680*6fee86a4SJeremy Kemp     Sampler(
5681*6fee86a4SJeremy Kemp         const Context& context,
5682*6fee86a4SJeremy Kemp         cl_bool normalized_coords,
5683*6fee86a4SJeremy Kemp         cl_addressing_mode addressing_mode,
5684*6fee86a4SJeremy Kemp         cl_filter_mode filter_mode,
5685*6fee86a4SJeremy Kemp         cl_int* err = nullptr)
5686*6fee86a4SJeremy Kemp     {
5687*6fee86a4SJeremy Kemp         cl_int error;
5688*6fee86a4SJeremy Kemp 
5689*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 200
5690*6fee86a4SJeremy Kemp         cl_sampler_properties sampler_properties[] = {
5691*6fee86a4SJeremy Kemp             CL_SAMPLER_NORMALIZED_COORDS, normalized_coords,
5692*6fee86a4SJeremy Kemp             CL_SAMPLER_ADDRESSING_MODE, addressing_mode,
5693*6fee86a4SJeremy Kemp             CL_SAMPLER_FILTER_MODE, filter_mode,
5694*6fee86a4SJeremy Kemp             0 };
5695*6fee86a4SJeremy Kemp         object_ = ::clCreateSamplerWithProperties(
5696*6fee86a4SJeremy Kemp             context(),
5697*6fee86a4SJeremy Kemp             sampler_properties,
5698*6fee86a4SJeremy Kemp             &error);
5699*6fee86a4SJeremy Kemp 
5700*6fee86a4SJeremy Kemp         detail::errHandler(error, __CREATE_SAMPLER_WITH_PROPERTIES_ERR);
5701*6fee86a4SJeremy Kemp         if (err != nullptr) {
5702*6fee86a4SJeremy Kemp             *err = error;
5703*6fee86a4SJeremy Kemp         }
5704*6fee86a4SJeremy Kemp #else
5705*6fee86a4SJeremy Kemp         object_ = ::clCreateSampler(
5706*6fee86a4SJeremy Kemp             context(),
5707*6fee86a4SJeremy Kemp             normalized_coords,
5708*6fee86a4SJeremy Kemp             addressing_mode,
5709*6fee86a4SJeremy Kemp             filter_mode,
5710*6fee86a4SJeremy Kemp             &error);
5711*6fee86a4SJeremy Kemp 
5712*6fee86a4SJeremy Kemp         detail::errHandler(error, __CREATE_SAMPLER_ERR);
5713*6fee86a4SJeremy Kemp         if (err != nullptr) {
5714*6fee86a4SJeremy Kemp             *err = error;
5715*6fee86a4SJeremy Kemp         }
5716*6fee86a4SJeremy Kemp #endif
5717*6fee86a4SJeremy Kemp     }
5718*6fee86a4SJeremy Kemp 
5719*6fee86a4SJeremy Kemp     /*! \brief Constructor from cl_sampler - takes ownership.
5720*6fee86a4SJeremy Kemp      *
5721*6fee86a4SJeremy Kemp      * \param retainObject will cause the constructor to retain its cl object.
5722*6fee86a4SJeremy Kemp      *                     Defaults to false to maintain compatibility with
5723*6fee86a4SJeremy Kemp      *                     earlier versions.
5724*6fee86a4SJeremy Kemp      *  This effectively transfers ownership of a refcount on the cl_sampler
5725*6fee86a4SJeremy Kemp      *  into the new Sampler object.
5726*6fee86a4SJeremy Kemp      */
Sampler(const cl_sampler & sampler,bool retainObject=false)5727*6fee86a4SJeremy Kemp     explicit Sampler(const cl_sampler& sampler, bool retainObject = false) :
5728*6fee86a4SJeremy Kemp         detail::Wrapper<cl_type>(sampler, retainObject) { }
5729*6fee86a4SJeremy Kemp 
5730*6fee86a4SJeremy Kemp     /*! \brief Assignment operator from cl_sampler - takes ownership.
5731*6fee86a4SJeremy Kemp      *
5732*6fee86a4SJeremy Kemp      *  This effectively transfers ownership of a refcount on the rhs and calls
5733*6fee86a4SJeremy Kemp      *  clReleaseSampler() on the value previously held by this instance.
5734*6fee86a4SJeremy Kemp      */
operator =(const cl_sampler & rhs)5735*6fee86a4SJeremy Kemp     Sampler& operator = (const cl_sampler& rhs)
5736*6fee86a4SJeremy Kemp     {
5737*6fee86a4SJeremy Kemp         detail::Wrapper<cl_type>::operator=(rhs);
5738*6fee86a4SJeremy Kemp         return *this;
5739*6fee86a4SJeremy Kemp     }
5740*6fee86a4SJeremy Kemp 
5741*6fee86a4SJeremy Kemp 
5742*6fee86a4SJeremy Kemp 
5743*6fee86a4SJeremy Kemp     //! \brief Wrapper for clGetSamplerInfo().
5744*6fee86a4SJeremy Kemp     template <typename T>
getInfo(cl_sampler_info name,T * param) const5745*6fee86a4SJeremy Kemp     cl_int getInfo(cl_sampler_info name, T* param) const
5746*6fee86a4SJeremy Kemp     {
5747*6fee86a4SJeremy Kemp         return detail::errHandler(
5748*6fee86a4SJeremy Kemp             detail::getInfo(&::clGetSamplerInfo, object_, name, param),
5749*6fee86a4SJeremy Kemp             __GET_SAMPLER_INFO_ERR);
5750*6fee86a4SJeremy Kemp     }
5751*6fee86a4SJeremy Kemp 
5752*6fee86a4SJeremy Kemp     //! \brief Wrapper for clGetSamplerInfo() that returns by value.
5753*6fee86a4SJeremy Kemp     template <cl_sampler_info name> typename
5754*6fee86a4SJeremy Kemp     detail::param_traits<detail::cl_sampler_info, name>::param_type
getInfo(cl_int * err=nullptr) const5755*6fee86a4SJeremy Kemp     getInfo(cl_int* err = nullptr) const
5756*6fee86a4SJeremy Kemp     {
5757*6fee86a4SJeremy Kemp         typename detail::param_traits<
5758*6fee86a4SJeremy Kemp             detail::cl_sampler_info, name>::param_type param;
5759*6fee86a4SJeremy Kemp         cl_int result = getInfo(name, &param);
5760*6fee86a4SJeremy Kemp         if (err != nullptr) {
5761*6fee86a4SJeremy Kemp             *err = result;
5762*6fee86a4SJeremy Kemp         }
5763*6fee86a4SJeremy Kemp         return param;
5764*6fee86a4SJeremy Kemp     }
5765*6fee86a4SJeremy Kemp };
5766*6fee86a4SJeremy Kemp 
5767*6fee86a4SJeremy Kemp class Program;
5768*6fee86a4SJeremy Kemp class CommandQueue;
5769*6fee86a4SJeremy Kemp class DeviceCommandQueue;
5770*6fee86a4SJeremy Kemp class Kernel;
5771*6fee86a4SJeremy Kemp 
5772*6fee86a4SJeremy Kemp //! \brief Class interface for specifying NDRange values.
5773*6fee86a4SJeremy Kemp class NDRange
5774*6fee86a4SJeremy Kemp {
5775*6fee86a4SJeremy Kemp private:
5776*6fee86a4SJeremy Kemp     size_type sizes_[3];
5777*6fee86a4SJeremy Kemp     cl_uint dimensions_;
5778*6fee86a4SJeremy Kemp 
5779*6fee86a4SJeremy Kemp public:
5780*6fee86a4SJeremy Kemp     //! \brief Default constructor - resulting range has zero dimensions.
NDRange()5781*6fee86a4SJeremy Kemp     NDRange()
5782*6fee86a4SJeremy Kemp         : dimensions_(0)
5783*6fee86a4SJeremy Kemp     {
5784*6fee86a4SJeremy Kemp         sizes_[0] = 0;
5785*6fee86a4SJeremy Kemp         sizes_[1] = 0;
5786*6fee86a4SJeremy Kemp         sizes_[2] = 0;
5787*6fee86a4SJeremy Kemp     }
5788*6fee86a4SJeremy Kemp 
5789*6fee86a4SJeremy Kemp     //! \brief Constructs one-dimensional range.
NDRange(size_type size0)5790*6fee86a4SJeremy Kemp     NDRange(size_type size0)
5791*6fee86a4SJeremy Kemp         : dimensions_(1)
5792*6fee86a4SJeremy Kemp     {
5793*6fee86a4SJeremy Kemp         sizes_[0] = size0;
5794*6fee86a4SJeremy Kemp         sizes_[1] = 1;
5795*6fee86a4SJeremy Kemp         sizes_[2] = 1;
5796*6fee86a4SJeremy Kemp     }
5797*6fee86a4SJeremy Kemp 
5798*6fee86a4SJeremy Kemp     //! \brief Constructs two-dimensional range.
NDRange(size_type size0,size_type size1)5799*6fee86a4SJeremy Kemp     NDRange(size_type size0, size_type size1)
5800*6fee86a4SJeremy Kemp         : dimensions_(2)
5801*6fee86a4SJeremy Kemp     {
5802*6fee86a4SJeremy Kemp         sizes_[0] = size0;
5803*6fee86a4SJeremy Kemp         sizes_[1] = size1;
5804*6fee86a4SJeremy Kemp         sizes_[2] = 1;
5805*6fee86a4SJeremy Kemp     }
5806*6fee86a4SJeremy Kemp 
5807*6fee86a4SJeremy Kemp     //! \brief Constructs three-dimensional range.
NDRange(size_type size0,size_type size1,size_type size2)5808*6fee86a4SJeremy Kemp     NDRange(size_type size0, size_type size1, size_type size2)
5809*6fee86a4SJeremy Kemp         : dimensions_(3)
5810*6fee86a4SJeremy Kemp     {
5811*6fee86a4SJeremy Kemp         sizes_[0] = size0;
5812*6fee86a4SJeremy Kemp         sizes_[1] = size1;
5813*6fee86a4SJeremy Kemp         sizes_[2] = size2;
5814*6fee86a4SJeremy Kemp     }
5815*6fee86a4SJeremy Kemp 
5816*6fee86a4SJeremy Kemp     //! \brief Constructs one-dimensional range.
NDRange(array<size_type,1> a)5817*6fee86a4SJeremy Kemp     NDRange(array<size_type, 1> a) : NDRange(a[0]){}
5818*6fee86a4SJeremy Kemp 
5819*6fee86a4SJeremy Kemp     //! \brief Constructs two-dimensional range.
NDRange(array<size_type,2> a)5820*6fee86a4SJeremy Kemp     NDRange(array<size_type, 2> a) : NDRange(a[0], a[1]){}
5821*6fee86a4SJeremy Kemp 
5822*6fee86a4SJeremy Kemp     //! \brief Constructs three-dimensional range.
NDRange(array<size_type,3> a)5823*6fee86a4SJeremy Kemp     NDRange(array<size_type, 3> a) : NDRange(a[0], a[1], a[2]){}
5824*6fee86a4SJeremy Kemp 
5825*6fee86a4SJeremy Kemp     /*! \brief Conversion operator to const size_type *.
5826*6fee86a4SJeremy Kemp      *
5827*6fee86a4SJeremy Kemp      *  \returns a pointer to the size of the first dimension.
5828*6fee86a4SJeremy Kemp      */
operator const size_type*() const5829*6fee86a4SJeremy Kemp     operator const size_type*() const {
5830*6fee86a4SJeremy Kemp         return sizes_;
5831*6fee86a4SJeremy Kemp     }
5832*6fee86a4SJeremy Kemp 
5833*6fee86a4SJeremy Kemp     //! \brief Queries the number of dimensions in the range.
dimensions() const5834*6fee86a4SJeremy Kemp     size_type dimensions() const
5835*6fee86a4SJeremy Kemp     {
5836*6fee86a4SJeremy Kemp         return dimensions_;
5837*6fee86a4SJeremy Kemp     }
5838*6fee86a4SJeremy Kemp 
5839*6fee86a4SJeremy Kemp     //! \brief Returns the size of the object in bytes based on the
5840*6fee86a4SJeremy Kemp     // runtime number of dimensions
size() const5841*6fee86a4SJeremy Kemp     size_type size() const
5842*6fee86a4SJeremy Kemp     {
5843*6fee86a4SJeremy Kemp         return dimensions_*sizeof(size_type);
5844*6fee86a4SJeremy Kemp     }
5845*6fee86a4SJeremy Kemp 
get()5846*6fee86a4SJeremy Kemp     size_type* get()
5847*6fee86a4SJeremy Kemp     {
5848*6fee86a4SJeremy Kemp         return sizes_;
5849*6fee86a4SJeremy Kemp     }
5850*6fee86a4SJeremy Kemp 
get() const5851*6fee86a4SJeremy Kemp     const size_type* get() const
5852*6fee86a4SJeremy Kemp     {
5853*6fee86a4SJeremy Kemp         return sizes_;
5854*6fee86a4SJeremy Kemp     }
5855*6fee86a4SJeremy Kemp };
5856*6fee86a4SJeremy Kemp 
5857*6fee86a4SJeremy Kemp //! \brief A zero-dimensional range.
5858*6fee86a4SJeremy Kemp static const NDRange NullRange;
5859*6fee86a4SJeremy Kemp 
5860*6fee86a4SJeremy Kemp //! \brief Local address wrapper for use with Kernel::setArg
5861*6fee86a4SJeremy Kemp struct LocalSpaceArg
5862*6fee86a4SJeremy Kemp {
5863*6fee86a4SJeremy Kemp     size_type size_;
5864*6fee86a4SJeremy Kemp };
5865*6fee86a4SJeremy Kemp 
5866*6fee86a4SJeremy Kemp namespace detail {
5867*6fee86a4SJeremy Kemp 
5868*6fee86a4SJeremy Kemp template <typename T, class Enable = void>
5869*6fee86a4SJeremy Kemp struct KernelArgumentHandler;
5870*6fee86a4SJeremy Kemp 
5871*6fee86a4SJeremy Kemp // Enable for objects that are not subclasses of memory
5872*6fee86a4SJeremy Kemp // Pointers, constants etc
5873*6fee86a4SJeremy Kemp template <typename T>
5874*6fee86a4SJeremy Kemp struct KernelArgumentHandler<T, typename std::enable_if<!std::is_base_of<cl::Memory, T>::value>::type>
5875*6fee86a4SJeremy Kemp {
sizecl::detail::KernelArgumentHandler5876*6fee86a4SJeremy Kemp     static size_type size(const T&) { return sizeof(T); }
ptrcl::detail::KernelArgumentHandler5877*6fee86a4SJeremy Kemp     static const T* ptr(const T& value) { return &value; }
5878*6fee86a4SJeremy Kemp };
5879*6fee86a4SJeremy Kemp 
5880*6fee86a4SJeremy Kemp // Enable for subclasses of memory where we want to get a reference to the cl_mem out
5881*6fee86a4SJeremy Kemp // and pass that in for safety
5882*6fee86a4SJeremy Kemp template <typename T>
5883*6fee86a4SJeremy Kemp struct KernelArgumentHandler<T, typename std::enable_if<std::is_base_of<cl::Memory, T>::value>::type>
5884*6fee86a4SJeremy Kemp {
sizecl::detail::KernelArgumentHandler5885*6fee86a4SJeremy Kemp     static size_type size(const T&) { return sizeof(cl_mem); }
ptrcl::detail::KernelArgumentHandler5886*6fee86a4SJeremy Kemp     static const cl_mem* ptr(const T& value) { return &(value()); }
5887*6fee86a4SJeremy Kemp };
5888*6fee86a4SJeremy Kemp 
5889*6fee86a4SJeremy Kemp // Specialization for DeviceCommandQueue defined later
5890*6fee86a4SJeremy Kemp 
5891*6fee86a4SJeremy Kemp template <>
5892*6fee86a4SJeremy Kemp struct KernelArgumentHandler<LocalSpaceArg, void>
5893*6fee86a4SJeremy Kemp {
sizecl::detail::KernelArgumentHandler5894*6fee86a4SJeremy Kemp     static size_type size(const LocalSpaceArg& value) { return value.size_; }
ptrcl::detail::KernelArgumentHandler5895*6fee86a4SJeremy Kemp     static const void* ptr(const LocalSpaceArg&) { return nullptr; }
5896*6fee86a4SJeremy Kemp };
5897*6fee86a4SJeremy Kemp 
5898*6fee86a4SJeremy Kemp }
5899*6fee86a4SJeremy Kemp //! \endcond
5900*6fee86a4SJeremy Kemp 
5901*6fee86a4SJeremy Kemp /*! Local
5902*6fee86a4SJeremy Kemp  * \brief Helper function for generating LocalSpaceArg objects.
5903*6fee86a4SJeremy Kemp  */
5904*6fee86a4SJeremy Kemp inline LocalSpaceArg
Local(size_type size)5905*6fee86a4SJeremy Kemp Local(size_type size)
5906*6fee86a4SJeremy Kemp {
5907*6fee86a4SJeremy Kemp     LocalSpaceArg ret = { size };
5908*6fee86a4SJeremy Kemp     return ret;
5909*6fee86a4SJeremy Kemp }
5910*6fee86a4SJeremy Kemp 
5911*6fee86a4SJeremy Kemp /*! \brief Class interface for cl_kernel.
5912*6fee86a4SJeremy Kemp  *
5913*6fee86a4SJeremy Kemp  *  \note Copies of these objects are shallow, meaning that the copy will refer
5914*6fee86a4SJeremy Kemp  *        to the same underlying cl_kernel as the original.  For details, see
5915*6fee86a4SJeremy Kemp  *        clRetainKernel() and clReleaseKernel().
5916*6fee86a4SJeremy Kemp  *
5917*6fee86a4SJeremy Kemp  *  \see cl_kernel
5918*6fee86a4SJeremy Kemp  */
5919*6fee86a4SJeremy Kemp class Kernel : public detail::Wrapper<cl_kernel>
5920*6fee86a4SJeremy Kemp {
5921*6fee86a4SJeremy Kemp public:
5922*6fee86a4SJeremy Kemp     inline Kernel(const Program& program, const char* name, cl_int* err = nullptr);
5923*6fee86a4SJeremy Kemp 
5924*6fee86a4SJeremy Kemp     //! \brief Default constructor - initializes to nullptr.
Kernel()5925*6fee86a4SJeremy Kemp     Kernel() { }
5926*6fee86a4SJeremy Kemp 
5927*6fee86a4SJeremy Kemp     /*! \brief Constructor from cl_kernel - takes ownership.
5928*6fee86a4SJeremy Kemp      *
5929*6fee86a4SJeremy Kemp      * \param retainObject will cause the constructor to retain its cl object.
5930*6fee86a4SJeremy Kemp      *                     Defaults to false to maintain compatibility with
5931*6fee86a4SJeremy Kemp      *                     earlier versions.
5932*6fee86a4SJeremy Kemp      *  This effectively transfers ownership of a refcount on the cl_kernel
5933*6fee86a4SJeremy Kemp      *  into the new Kernel object.
5934*6fee86a4SJeremy Kemp      */
Kernel(const cl_kernel & kernel,bool retainObject=false)5935*6fee86a4SJeremy Kemp     explicit Kernel(const cl_kernel& kernel, bool retainObject = false) :
5936*6fee86a4SJeremy Kemp         detail::Wrapper<cl_type>(kernel, retainObject) { }
5937*6fee86a4SJeremy Kemp 
5938*6fee86a4SJeremy Kemp     /*! \brief Assignment operator from cl_kernel - takes ownership.
5939*6fee86a4SJeremy Kemp      *
5940*6fee86a4SJeremy Kemp      *  This effectively transfers ownership of a refcount on the rhs and calls
5941*6fee86a4SJeremy Kemp      *  clReleaseKernel() on the value previously held by this instance.
5942*6fee86a4SJeremy Kemp      */
operator =(const cl_kernel & rhs)5943*6fee86a4SJeremy Kemp     Kernel& operator = (const cl_kernel& rhs)
5944*6fee86a4SJeremy Kemp     {
5945*6fee86a4SJeremy Kemp         detail::Wrapper<cl_type>::operator=(rhs);
5946*6fee86a4SJeremy Kemp         return *this;
5947*6fee86a4SJeremy Kemp     }
5948*6fee86a4SJeremy Kemp 
5949*6fee86a4SJeremy Kemp 
5950*6fee86a4SJeremy Kemp 
5951*6fee86a4SJeremy Kemp 
5952*6fee86a4SJeremy Kemp     template <typename T>
getInfo(cl_kernel_info name,T * param) const5953*6fee86a4SJeremy Kemp     cl_int getInfo(cl_kernel_info name, T* param) const
5954*6fee86a4SJeremy Kemp     {
5955*6fee86a4SJeremy Kemp         return detail::errHandler(
5956*6fee86a4SJeremy Kemp             detail::getInfo(&::clGetKernelInfo, object_, name, param),
5957*6fee86a4SJeremy Kemp             __GET_KERNEL_INFO_ERR);
5958*6fee86a4SJeremy Kemp     }
5959*6fee86a4SJeremy Kemp 
5960*6fee86a4SJeremy Kemp     template <cl_kernel_info name> typename
5961*6fee86a4SJeremy Kemp     detail::param_traits<detail::cl_kernel_info, name>::param_type
getInfo(cl_int * err=nullptr) const5962*6fee86a4SJeremy Kemp     getInfo(cl_int* err = nullptr) const
5963*6fee86a4SJeremy Kemp     {
5964*6fee86a4SJeremy Kemp         typename detail::param_traits<
5965*6fee86a4SJeremy Kemp             detail::cl_kernel_info, name>::param_type param;
5966*6fee86a4SJeremy Kemp         cl_int result = getInfo(name, &param);
5967*6fee86a4SJeremy Kemp         if (err != nullptr) {
5968*6fee86a4SJeremy Kemp             *err = result;
5969*6fee86a4SJeremy Kemp         }
5970*6fee86a4SJeremy Kemp         return param;
5971*6fee86a4SJeremy Kemp     }
5972*6fee86a4SJeremy Kemp 
5973*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 120
5974*6fee86a4SJeremy Kemp     template <typename T>
getArgInfo(cl_uint argIndex,cl_kernel_arg_info name,T * param) const5975*6fee86a4SJeremy Kemp     cl_int getArgInfo(cl_uint argIndex, cl_kernel_arg_info name, T* param) const
5976*6fee86a4SJeremy Kemp     {
5977*6fee86a4SJeremy Kemp         return detail::errHandler(
5978*6fee86a4SJeremy Kemp             detail::getInfo(&::clGetKernelArgInfo, object_, argIndex, name, param),
5979*6fee86a4SJeremy Kemp             __GET_KERNEL_ARG_INFO_ERR);
5980*6fee86a4SJeremy Kemp     }
5981*6fee86a4SJeremy Kemp 
5982*6fee86a4SJeremy Kemp     template <cl_kernel_arg_info name> typename
5983*6fee86a4SJeremy Kemp     detail::param_traits<detail::cl_kernel_arg_info, name>::param_type
getArgInfo(cl_uint argIndex,cl_int * err=nullptr) const5984*6fee86a4SJeremy Kemp     getArgInfo(cl_uint argIndex, cl_int* err = nullptr) const
5985*6fee86a4SJeremy Kemp     {
5986*6fee86a4SJeremy Kemp         typename detail::param_traits<
5987*6fee86a4SJeremy Kemp             detail::cl_kernel_arg_info, name>::param_type param;
5988*6fee86a4SJeremy Kemp         cl_int result = getArgInfo(argIndex, name, &param);
5989*6fee86a4SJeremy Kemp         if (err != nullptr) {
5990*6fee86a4SJeremy Kemp             *err = result;
5991*6fee86a4SJeremy Kemp         }
5992*6fee86a4SJeremy Kemp         return param;
5993*6fee86a4SJeremy Kemp     }
5994*6fee86a4SJeremy Kemp #endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
5995*6fee86a4SJeremy Kemp 
5996*6fee86a4SJeremy Kemp     template <typename T>
getWorkGroupInfo(const Device & device,cl_kernel_work_group_info name,T * param) const5997*6fee86a4SJeremy Kemp     cl_int getWorkGroupInfo(
5998*6fee86a4SJeremy Kemp         const Device& device, cl_kernel_work_group_info name, T* param) const
5999*6fee86a4SJeremy Kemp     {
6000*6fee86a4SJeremy Kemp         return detail::errHandler(
6001*6fee86a4SJeremy Kemp             detail::getInfo(
6002*6fee86a4SJeremy Kemp                 &::clGetKernelWorkGroupInfo, object_, device(), name, param),
6003*6fee86a4SJeremy Kemp                 __GET_KERNEL_WORK_GROUP_INFO_ERR);
6004*6fee86a4SJeremy Kemp     }
6005*6fee86a4SJeremy Kemp 
6006*6fee86a4SJeremy Kemp     template <cl_kernel_work_group_info name> typename
6007*6fee86a4SJeremy Kemp     detail::param_traits<detail::cl_kernel_work_group_info, name>::param_type
getWorkGroupInfo(const Device & device,cl_int * err=nullptr) const6008*6fee86a4SJeremy Kemp         getWorkGroupInfo(const Device& device, cl_int* err = nullptr) const
6009*6fee86a4SJeremy Kemp     {
6010*6fee86a4SJeremy Kemp         typename detail::param_traits<
6011*6fee86a4SJeremy Kemp         detail::cl_kernel_work_group_info, name>::param_type param;
6012*6fee86a4SJeremy Kemp         cl_int result = getWorkGroupInfo(device, name, &param);
6013*6fee86a4SJeremy Kemp         if (err != nullptr) {
6014*6fee86a4SJeremy Kemp             *err = result;
6015*6fee86a4SJeremy Kemp         }
6016*6fee86a4SJeremy Kemp         return param;
6017*6fee86a4SJeremy Kemp     }
6018*6fee86a4SJeremy Kemp 
6019*6fee86a4SJeremy Kemp #if defined(CL_HPP_USE_CL_SUB_GROUPS_KHR) || CL_HPP_TARGET_OPENCL_VERSION >= 210
getSubGroupInfo(const cl::Device & dev,cl_kernel_sub_group_info name,const cl::NDRange & range,size_type * param) const6020*6fee86a4SJeremy Kemp     cl_int getSubGroupInfo(const cl::Device &dev, cl_kernel_sub_group_info name, const cl::NDRange &range, size_type* param) const
6021*6fee86a4SJeremy Kemp     {
6022*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 210
6023*6fee86a4SJeremy Kemp 
6024*6fee86a4SJeremy Kemp         return detail::errHandler(
6025*6fee86a4SJeremy Kemp             clGetKernelSubGroupInfo(object_, dev(), name, range.size(), range.get(), sizeof(size_type), param, nullptr),
6026*6fee86a4SJeremy Kemp             __GET_KERNEL_SUB_GROUP_INFO_ERR);
6027*6fee86a4SJeremy Kemp 
6028*6fee86a4SJeremy Kemp #else // #if CL_HPP_TARGET_OPENCL_VERSION >= 210
6029*6fee86a4SJeremy Kemp 
6030*6fee86a4SJeremy Kemp         typedef clGetKernelSubGroupInfoKHR_fn PFN_clGetKernelSubGroupInfoKHR;
6031*6fee86a4SJeremy Kemp         static PFN_clGetKernelSubGroupInfoKHR pfn_clGetKernelSubGroupInfoKHR = nullptr;
6032*6fee86a4SJeremy Kemp         CL_HPP_INIT_CL_EXT_FCN_PTR_(clGetKernelSubGroupInfoKHR);
6033*6fee86a4SJeremy Kemp 
6034*6fee86a4SJeremy Kemp         return detail::errHandler(
6035*6fee86a4SJeremy Kemp             pfn_clGetKernelSubGroupInfoKHR(object_, dev(), name, range.size(), range.get(), sizeof(size_type), param, nullptr),
6036*6fee86a4SJeremy Kemp             __GET_KERNEL_SUB_GROUP_INFO_ERR);
6037*6fee86a4SJeremy Kemp 
6038*6fee86a4SJeremy Kemp #endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 210
6039*6fee86a4SJeremy Kemp     }
6040*6fee86a4SJeremy Kemp 
6041*6fee86a4SJeremy Kemp     template <cl_kernel_sub_group_info name>
getSubGroupInfo(const cl::Device & dev,const cl::NDRange & range,cl_int * err=nullptr) const6042*6fee86a4SJeremy Kemp         size_type getSubGroupInfo(const cl::Device &dev, const cl::NDRange &range, cl_int* err = nullptr) const
6043*6fee86a4SJeremy Kemp     {
6044*6fee86a4SJeremy Kemp         size_type param;
6045*6fee86a4SJeremy Kemp         cl_int result = getSubGroupInfo(dev, name, range, &param);
6046*6fee86a4SJeremy Kemp         if (err != nullptr) {
6047*6fee86a4SJeremy Kemp             *err = result;
6048*6fee86a4SJeremy Kemp         }
6049*6fee86a4SJeremy Kemp         return param;
6050*6fee86a4SJeremy Kemp     }
6051*6fee86a4SJeremy Kemp #endif // defined(CL_HPP_USE_CL_SUB_GROUPS_KHR) || CL_HPP_TARGET_OPENCL_VERSION >= 210
6052*6fee86a4SJeremy Kemp 
6053*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 200
6054*6fee86a4SJeremy Kemp     /*! \brief setArg overload taking a shared_ptr type
6055*6fee86a4SJeremy Kemp      */
6056*6fee86a4SJeremy Kemp     template<typename T, class D>
setArg(cl_uint index,const cl::pointer<T,D> & argPtr)6057*6fee86a4SJeremy Kemp     cl_int setArg(cl_uint index, const cl::pointer<T, D> &argPtr)
6058*6fee86a4SJeremy Kemp     {
6059*6fee86a4SJeremy Kemp         return detail::errHandler(
6060*6fee86a4SJeremy Kemp             ::clSetKernelArgSVMPointer(object_, index, argPtr.get()),
6061*6fee86a4SJeremy Kemp             __SET_KERNEL_ARGS_ERR);
6062*6fee86a4SJeremy Kemp     }
6063*6fee86a4SJeremy Kemp 
6064*6fee86a4SJeremy Kemp     /*! \brief setArg overload taking a vector type.
6065*6fee86a4SJeremy Kemp      */
6066*6fee86a4SJeremy Kemp     template<typename T, class Alloc>
setArg(cl_uint index,const cl::vector<T,Alloc> & argPtr)6067*6fee86a4SJeremy Kemp     cl_int setArg(cl_uint index, const cl::vector<T, Alloc> &argPtr)
6068*6fee86a4SJeremy Kemp     {
6069*6fee86a4SJeremy Kemp         return detail::errHandler(
6070*6fee86a4SJeremy Kemp             ::clSetKernelArgSVMPointer(object_, index, argPtr.data()),
6071*6fee86a4SJeremy Kemp             __SET_KERNEL_ARGS_ERR);
6072*6fee86a4SJeremy Kemp     }
6073*6fee86a4SJeremy Kemp 
6074*6fee86a4SJeremy Kemp     /*! \brief setArg overload taking a pointer type
6075*6fee86a4SJeremy Kemp      */
6076*6fee86a4SJeremy Kemp     template<typename T>
6077*6fee86a4SJeremy Kemp     typename std::enable_if<std::is_pointer<T>::value, cl_int>::type
setArg(cl_uint index,const T argPtr)6078*6fee86a4SJeremy Kemp         setArg(cl_uint index, const T argPtr)
6079*6fee86a4SJeremy Kemp     {
6080*6fee86a4SJeremy Kemp         return detail::errHandler(
6081*6fee86a4SJeremy Kemp             ::clSetKernelArgSVMPointer(object_, index, argPtr),
6082*6fee86a4SJeremy Kemp             __SET_KERNEL_ARGS_ERR);
6083*6fee86a4SJeremy Kemp     }
6084*6fee86a4SJeremy Kemp #endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 200
6085*6fee86a4SJeremy Kemp 
6086*6fee86a4SJeremy Kemp     /*! \brief setArg overload taking a POD type
6087*6fee86a4SJeremy Kemp      */
6088*6fee86a4SJeremy Kemp     template <typename T>
6089*6fee86a4SJeremy Kemp     typename std::enable_if<!std::is_pointer<T>::value, cl_int>::type
setArg(cl_uint index,const T & value)6090*6fee86a4SJeremy Kemp         setArg(cl_uint index, const T &value)
6091*6fee86a4SJeremy Kemp     {
6092*6fee86a4SJeremy Kemp         return detail::errHandler(
6093*6fee86a4SJeremy Kemp             ::clSetKernelArg(
6094*6fee86a4SJeremy Kemp                 object_,
6095*6fee86a4SJeremy Kemp                 index,
6096*6fee86a4SJeremy Kemp                 detail::KernelArgumentHandler<T>::size(value),
6097*6fee86a4SJeremy Kemp                 detail::KernelArgumentHandler<T>::ptr(value)),
6098*6fee86a4SJeremy Kemp             __SET_KERNEL_ARGS_ERR);
6099*6fee86a4SJeremy Kemp     }
6100*6fee86a4SJeremy Kemp 
setArg(cl_uint index,size_type size,const void * argPtr)6101*6fee86a4SJeremy Kemp     cl_int setArg(cl_uint index, size_type size, const void* argPtr)
6102*6fee86a4SJeremy Kemp     {
6103*6fee86a4SJeremy Kemp         return detail::errHandler(
6104*6fee86a4SJeremy Kemp             ::clSetKernelArg(object_, index, size, argPtr),
6105*6fee86a4SJeremy Kemp             __SET_KERNEL_ARGS_ERR);
6106*6fee86a4SJeremy Kemp     }
6107*6fee86a4SJeremy Kemp 
6108*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 200
6109*6fee86a4SJeremy Kemp     /*!
6110*6fee86a4SJeremy Kemp      * Specify a vector of SVM pointers that the kernel may access in
6111*6fee86a4SJeremy Kemp      * addition to its arguments.
6112*6fee86a4SJeremy Kemp      */
setSVMPointers(const vector<void * > & pointerList)6113*6fee86a4SJeremy Kemp     cl_int setSVMPointers(const vector<void*> &pointerList)
6114*6fee86a4SJeremy Kemp     {
6115*6fee86a4SJeremy Kemp         return detail::errHandler(
6116*6fee86a4SJeremy Kemp             ::clSetKernelExecInfo(
6117*6fee86a4SJeremy Kemp                 object_,
6118*6fee86a4SJeremy Kemp                 CL_KERNEL_EXEC_INFO_SVM_PTRS,
6119*6fee86a4SJeremy Kemp                 sizeof(void*)*pointerList.size(),
6120*6fee86a4SJeremy Kemp                 pointerList.data()));
6121*6fee86a4SJeremy Kemp     }
6122*6fee86a4SJeremy Kemp 
6123*6fee86a4SJeremy Kemp     /*!
6124*6fee86a4SJeremy Kemp      * Specify a std::array of SVM pointers that the kernel may access in
6125*6fee86a4SJeremy Kemp      * addition to its arguments.
6126*6fee86a4SJeremy Kemp      */
6127*6fee86a4SJeremy Kemp     template<int ArrayLength>
setSVMPointers(const std::array<void *,ArrayLength> & pointerList)6128*6fee86a4SJeremy Kemp     cl_int setSVMPointers(const std::array<void*, ArrayLength> &pointerList)
6129*6fee86a4SJeremy Kemp     {
6130*6fee86a4SJeremy Kemp         return detail::errHandler(
6131*6fee86a4SJeremy Kemp             ::clSetKernelExecInfo(
6132*6fee86a4SJeremy Kemp                 object_,
6133*6fee86a4SJeremy Kemp                 CL_KERNEL_EXEC_INFO_SVM_PTRS,
6134*6fee86a4SJeremy Kemp                 sizeof(void*)*pointerList.size(),
6135*6fee86a4SJeremy Kemp                 pointerList.data()));
6136*6fee86a4SJeremy Kemp     }
6137*6fee86a4SJeremy Kemp 
6138*6fee86a4SJeremy Kemp     /*! \brief Enable fine-grained system SVM.
6139*6fee86a4SJeremy Kemp      *
6140*6fee86a4SJeremy Kemp      * \note It is only possible to enable fine-grained system SVM if all devices
6141*6fee86a4SJeremy Kemp      *       in the context associated with kernel support it.
6142*6fee86a4SJeremy Kemp      *
6143*6fee86a4SJeremy Kemp      * \param svmEnabled True if fine-grained system SVM is requested. False otherwise.
6144*6fee86a4SJeremy Kemp      * \return CL_SUCCESS if the function was executed succesfully. CL_INVALID_OPERATION
6145*6fee86a4SJeremy Kemp      *         if no devices in the context support fine-grained system SVM.
6146*6fee86a4SJeremy Kemp      *
6147*6fee86a4SJeremy Kemp      * \see clSetKernelExecInfo
6148*6fee86a4SJeremy Kemp      */
enableFineGrainedSystemSVM(bool svmEnabled)6149*6fee86a4SJeremy Kemp     cl_int enableFineGrainedSystemSVM(bool svmEnabled)
6150*6fee86a4SJeremy Kemp     {
6151*6fee86a4SJeremy Kemp         cl_bool svmEnabled_ = svmEnabled ? CL_TRUE : CL_FALSE;
6152*6fee86a4SJeremy Kemp         return detail::errHandler(
6153*6fee86a4SJeremy Kemp             ::clSetKernelExecInfo(
6154*6fee86a4SJeremy Kemp                 object_,
6155*6fee86a4SJeremy Kemp                 CL_KERNEL_EXEC_INFO_SVM_FINE_GRAIN_SYSTEM,
6156*6fee86a4SJeremy Kemp                 sizeof(cl_bool),
6157*6fee86a4SJeremy Kemp                 &svmEnabled_
6158*6fee86a4SJeremy Kemp                 )
6159*6fee86a4SJeremy Kemp             );
6160*6fee86a4SJeremy Kemp     }
6161*6fee86a4SJeremy Kemp 
6162*6fee86a4SJeremy Kemp     template<int index, int ArrayLength, class D, typename T0, typename T1, typename... Ts>
setSVMPointersHelper(std::array<void *,ArrayLength> & pointerList,const pointer<T0,D> & t0,const pointer<T1,D> & t1,Ts &...ts)6163*6fee86a4SJeremy Kemp     void setSVMPointersHelper(std::array<void*, ArrayLength> &pointerList, const pointer<T0, D> &t0, const pointer<T1, D> &t1, Ts & ... ts)
6164*6fee86a4SJeremy Kemp     {
6165*6fee86a4SJeremy Kemp         pointerList[index] = static_cast<void*>(t0.get());
6166*6fee86a4SJeremy Kemp         setSVMPointersHelper<index + 1, ArrayLength>(pointerList, t1, ts...);
6167*6fee86a4SJeremy Kemp     }
6168*6fee86a4SJeremy Kemp 
6169*6fee86a4SJeremy Kemp     template<int index, int ArrayLength, typename T0, typename T1, typename... Ts>
6170*6fee86a4SJeremy Kemp     typename std::enable_if<std::is_pointer<T0>::value, void>::type
setSVMPointersHelper(std::array<void *,ArrayLength> & pointerList,T0 t0,T1 t1,Ts...ts)6171*6fee86a4SJeremy Kemp     setSVMPointersHelper(std::array<void*, ArrayLength> &pointerList, T0 t0, T1 t1, Ts... ts)
6172*6fee86a4SJeremy Kemp     {
6173*6fee86a4SJeremy Kemp         pointerList[index] = static_cast<void*>(t0);
6174*6fee86a4SJeremy Kemp         setSVMPointersHelper<index + 1, ArrayLength>(pointerList, t1, ts...);
6175*6fee86a4SJeremy Kemp     }
6176*6fee86a4SJeremy Kemp 
6177*6fee86a4SJeremy Kemp     template<int index, int ArrayLength, typename T0, class D>
setSVMPointersHelper(std::array<void *,ArrayLength> & pointerList,const pointer<T0,D> & t0)6178*6fee86a4SJeremy Kemp     void setSVMPointersHelper(std::array<void*, ArrayLength> &pointerList, const pointer<T0, D> &t0)
6179*6fee86a4SJeremy Kemp     {
6180*6fee86a4SJeremy Kemp         pointerList[index] = static_cast<void*>(t0.get());
6181*6fee86a4SJeremy Kemp     }
6182*6fee86a4SJeremy Kemp 
6183*6fee86a4SJeremy Kemp 
6184*6fee86a4SJeremy Kemp     template<int index, int ArrayLength, typename T0>
6185*6fee86a4SJeremy Kemp     typename std::enable_if<std::is_pointer<T0>::value, void>::type
setSVMPointersHelper(std::array<void *,ArrayLength> & pointerList,T0 t0)6186*6fee86a4SJeremy Kemp     setSVMPointersHelper(std::array<void*, ArrayLength> &pointerList, T0 t0)
6187*6fee86a4SJeremy Kemp     {
6188*6fee86a4SJeremy Kemp         pointerList[index] = static_cast<void*>(t0);
6189*6fee86a4SJeremy Kemp     }
6190*6fee86a4SJeremy Kemp 
6191*6fee86a4SJeremy Kemp     template<typename T0, typename... Ts>
setSVMPointers(const T0 & t0,Ts &...ts)6192*6fee86a4SJeremy Kemp     cl_int setSVMPointers(const T0 &t0, Ts & ... ts)
6193*6fee86a4SJeremy Kemp     {
6194*6fee86a4SJeremy Kemp         std::array<void*, 1 + sizeof...(Ts)> pointerList;
6195*6fee86a4SJeremy Kemp 
6196*6fee86a4SJeremy Kemp         setSVMPointersHelper<0, 1 + sizeof...(Ts)>(pointerList, t0, ts...);
6197*6fee86a4SJeremy Kemp         return detail::errHandler(
6198*6fee86a4SJeremy Kemp             ::clSetKernelExecInfo(
6199*6fee86a4SJeremy Kemp             object_,
6200*6fee86a4SJeremy Kemp             CL_KERNEL_EXEC_INFO_SVM_PTRS,
6201*6fee86a4SJeremy Kemp             sizeof(void*)*(1 + sizeof...(Ts)),
6202*6fee86a4SJeremy Kemp             pointerList.data()));
6203*6fee86a4SJeremy Kemp     }
6204*6fee86a4SJeremy Kemp 
6205*6fee86a4SJeremy Kemp     template<typename T>
setExecInfo(cl_kernel_exec_info param_name,const T & val)6206*6fee86a4SJeremy Kemp     cl_int setExecInfo(cl_kernel_exec_info param_name, const T& val)
6207*6fee86a4SJeremy Kemp     {
6208*6fee86a4SJeremy Kemp         return detail::errHandler(
6209*6fee86a4SJeremy Kemp             ::clSetKernelExecInfo(
6210*6fee86a4SJeremy Kemp             object_,
6211*6fee86a4SJeremy Kemp             param_name,
6212*6fee86a4SJeremy Kemp             sizeof(T),
6213*6fee86a4SJeremy Kemp             &val));
6214*6fee86a4SJeremy Kemp     }
6215*6fee86a4SJeremy Kemp 
6216*6fee86a4SJeremy Kemp     template<cl_kernel_exec_info name>
setExecInfo(typename detail::param_traits<detail::cl_kernel_exec_info,name>::param_type & val)6217*6fee86a4SJeremy Kemp     cl_int setExecInfo(typename detail::param_traits<detail::cl_kernel_exec_info, name>::param_type& val)
6218*6fee86a4SJeremy Kemp     {
6219*6fee86a4SJeremy Kemp         return setExecInfo(name, val);
6220*6fee86a4SJeremy Kemp     }
6221*6fee86a4SJeremy Kemp #endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 200
6222*6fee86a4SJeremy Kemp 
6223*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 210
6224*6fee86a4SJeremy Kemp     /**
6225*6fee86a4SJeremy Kemp      * Make a deep copy of the kernel object including its arguments.
6226*6fee86a4SJeremy Kemp      * @return A new kernel object with internal state entirely separate from that
6227*6fee86a4SJeremy Kemp      *         of the original but with any arguments set on the original intact.
6228*6fee86a4SJeremy Kemp      */
clone()6229*6fee86a4SJeremy Kemp     Kernel clone()
6230*6fee86a4SJeremy Kemp     {
6231*6fee86a4SJeremy Kemp         cl_int error;
6232*6fee86a4SJeremy Kemp         Kernel retValue(clCloneKernel(this->get(), &error));
6233*6fee86a4SJeremy Kemp 
6234*6fee86a4SJeremy Kemp         detail::errHandler(error, __CLONE_KERNEL_ERR);
6235*6fee86a4SJeremy Kemp         return retValue;
6236*6fee86a4SJeremy Kemp     }
6237*6fee86a4SJeremy Kemp #endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 210
6238*6fee86a4SJeremy Kemp };
6239*6fee86a4SJeremy Kemp 
6240*6fee86a4SJeremy Kemp /*! \class Program
6241*6fee86a4SJeremy Kemp  * \brief Program interface that implements cl_program.
6242*6fee86a4SJeremy Kemp  */
6243*6fee86a4SJeremy Kemp class Program : public detail::Wrapper<cl_program>
6244*6fee86a4SJeremy Kemp {
6245*6fee86a4SJeremy Kemp public:
6246*6fee86a4SJeremy Kemp #if !defined(CL_HPP_ENABLE_PROGRAM_CONSTRUCTION_FROM_ARRAY_COMPATIBILITY)
6247*6fee86a4SJeremy Kemp     typedef vector<vector<unsigned char>> Binaries;
6248*6fee86a4SJeremy Kemp     typedef vector<string> Sources;
6249*6fee86a4SJeremy Kemp #else // #if !defined(CL_HPP_ENABLE_PROGRAM_CONSTRUCTION_FROM_ARRAY_COMPATIBILITY)
6250*6fee86a4SJeremy Kemp     typedef vector<std::pair<const void*, size_type> > Binaries;
6251*6fee86a4SJeremy Kemp     typedef vector<std::pair<const char*, size_type> > Sources;
6252*6fee86a4SJeremy Kemp #endif // #if !defined(CL_HPP_ENABLE_PROGRAM_CONSTRUCTION_FROM_ARRAY_COMPATIBILITY)
6253*6fee86a4SJeremy Kemp 
Program(const string & source,bool build=false,cl_int * err=nullptr)6254*6fee86a4SJeremy Kemp     Program(
6255*6fee86a4SJeremy Kemp         const string& source,
6256*6fee86a4SJeremy Kemp         bool build = false,
6257*6fee86a4SJeremy Kemp         cl_int* err = nullptr)
6258*6fee86a4SJeremy Kemp     {
6259*6fee86a4SJeremy Kemp         cl_int error;
6260*6fee86a4SJeremy Kemp 
6261*6fee86a4SJeremy Kemp         const char * strings = source.c_str();
6262*6fee86a4SJeremy Kemp         const size_type length  = source.size();
6263*6fee86a4SJeremy Kemp 
6264*6fee86a4SJeremy Kemp         Context context = Context::getDefault(err);
6265*6fee86a4SJeremy Kemp 
6266*6fee86a4SJeremy Kemp         object_ = ::clCreateProgramWithSource(
6267*6fee86a4SJeremy Kemp             context(), (cl_uint)1, &strings, &length, &error);
6268*6fee86a4SJeremy Kemp 
6269*6fee86a4SJeremy Kemp         detail::errHandler(error, __CREATE_PROGRAM_WITH_SOURCE_ERR);
6270*6fee86a4SJeremy Kemp 
6271*6fee86a4SJeremy Kemp         if (error == CL_SUCCESS && build) {
6272*6fee86a4SJeremy Kemp 
6273*6fee86a4SJeremy Kemp             error = ::clBuildProgram(
6274*6fee86a4SJeremy Kemp                 object_,
6275*6fee86a4SJeremy Kemp                 0,
6276*6fee86a4SJeremy Kemp                 nullptr,
6277*6fee86a4SJeremy Kemp #if !defined(CL_HPP_CL_1_2_DEFAULT_BUILD)
6278*6fee86a4SJeremy Kemp                 "-cl-std=CL2.0",
6279*6fee86a4SJeremy Kemp #else
6280*6fee86a4SJeremy Kemp                 "",
6281*6fee86a4SJeremy Kemp #endif // #if !defined(CL_HPP_CL_1_2_DEFAULT_BUILD)
6282*6fee86a4SJeremy Kemp                 nullptr,
6283*6fee86a4SJeremy Kemp                 nullptr);
6284*6fee86a4SJeremy Kemp 
6285*6fee86a4SJeremy Kemp             detail::buildErrHandler(error, __BUILD_PROGRAM_ERR, getBuildInfo<CL_PROGRAM_BUILD_LOG>());
6286*6fee86a4SJeremy Kemp         }
6287*6fee86a4SJeremy Kemp 
6288*6fee86a4SJeremy Kemp         if (err != nullptr) {
6289*6fee86a4SJeremy Kemp             *err = error;
6290*6fee86a4SJeremy Kemp         }
6291*6fee86a4SJeremy Kemp     }
6292*6fee86a4SJeremy Kemp 
Program(const Context & context,const string & source,bool build=false,cl_int * err=nullptr)6293*6fee86a4SJeremy Kemp     Program(
6294*6fee86a4SJeremy Kemp         const Context& context,
6295*6fee86a4SJeremy Kemp         const string& source,
6296*6fee86a4SJeremy Kemp         bool build = false,
6297*6fee86a4SJeremy Kemp         cl_int* err = nullptr)
6298*6fee86a4SJeremy Kemp     {
6299*6fee86a4SJeremy Kemp         cl_int error;
6300*6fee86a4SJeremy Kemp 
6301*6fee86a4SJeremy Kemp         const char * strings = source.c_str();
6302*6fee86a4SJeremy Kemp         const size_type length  = source.size();
6303*6fee86a4SJeremy Kemp 
6304*6fee86a4SJeremy Kemp         object_ = ::clCreateProgramWithSource(
6305*6fee86a4SJeremy Kemp             context(), (cl_uint)1, &strings, &length, &error);
6306*6fee86a4SJeremy Kemp 
6307*6fee86a4SJeremy Kemp         detail::errHandler(error, __CREATE_PROGRAM_WITH_SOURCE_ERR);
6308*6fee86a4SJeremy Kemp 
6309*6fee86a4SJeremy Kemp         if (error == CL_SUCCESS && build) {
6310*6fee86a4SJeremy Kemp             error = ::clBuildProgram(
6311*6fee86a4SJeremy Kemp                 object_,
6312*6fee86a4SJeremy Kemp                 0,
6313*6fee86a4SJeremy Kemp                 nullptr,
6314*6fee86a4SJeremy Kemp #if !defined(CL_HPP_CL_1_2_DEFAULT_BUILD)
6315*6fee86a4SJeremy Kemp                 "-cl-std=CL2.0",
6316*6fee86a4SJeremy Kemp #else
6317*6fee86a4SJeremy Kemp                 "",
6318*6fee86a4SJeremy Kemp #endif // #if !defined(CL_HPP_CL_1_2_DEFAULT_BUILD)
6319*6fee86a4SJeremy Kemp                 nullptr,
6320*6fee86a4SJeremy Kemp                 nullptr);
6321*6fee86a4SJeremy Kemp 
6322*6fee86a4SJeremy Kemp             detail::buildErrHandler(error, __BUILD_PROGRAM_ERR, getBuildInfo<CL_PROGRAM_BUILD_LOG>());
6323*6fee86a4SJeremy Kemp         }
6324*6fee86a4SJeremy Kemp 
6325*6fee86a4SJeremy Kemp         if (err != nullptr) {
6326*6fee86a4SJeremy Kemp             *err = error;
6327*6fee86a4SJeremy Kemp         }
6328*6fee86a4SJeremy Kemp     }
6329*6fee86a4SJeremy Kemp 
6330*6fee86a4SJeremy Kemp     /**
6331*6fee86a4SJeremy Kemp      * Create a program from a vector of source strings and the default context.
6332*6fee86a4SJeremy Kemp      * Does not compile or link the program.
6333*6fee86a4SJeremy Kemp      */
Program(const Sources & sources,cl_int * err=nullptr)6334*6fee86a4SJeremy Kemp     Program(
6335*6fee86a4SJeremy Kemp         const Sources& sources,
6336*6fee86a4SJeremy Kemp         cl_int* err = nullptr)
6337*6fee86a4SJeremy Kemp     {
6338*6fee86a4SJeremy Kemp         cl_int error;
6339*6fee86a4SJeremy Kemp         Context context = Context::getDefault(err);
6340*6fee86a4SJeremy Kemp 
6341*6fee86a4SJeremy Kemp         const size_type n = (size_type)sources.size();
6342*6fee86a4SJeremy Kemp 
6343*6fee86a4SJeremy Kemp         vector<size_type> lengths(n);
6344*6fee86a4SJeremy Kemp         vector<const char*> strings(n);
6345*6fee86a4SJeremy Kemp 
6346*6fee86a4SJeremy Kemp         for (size_type i = 0; i < n; ++i) {
6347*6fee86a4SJeremy Kemp #if !defined(CL_HPP_ENABLE_PROGRAM_CONSTRUCTION_FROM_ARRAY_COMPATIBILITY)
6348*6fee86a4SJeremy Kemp             strings[i] = sources[(int)i].data();
6349*6fee86a4SJeremy Kemp             lengths[i] = sources[(int)i].length();
6350*6fee86a4SJeremy Kemp #else // #if !defined(CL_HPP_ENABLE_PROGRAM_CONSTRUCTION_FROM_ARRAY_COMPATIBILITY)
6351*6fee86a4SJeremy Kemp             strings[i] = sources[(int)i].first;
6352*6fee86a4SJeremy Kemp             lengths[i] = sources[(int)i].second;
6353*6fee86a4SJeremy Kemp #endif // #if !defined(CL_HPP_ENABLE_PROGRAM_CONSTRUCTION_FROM_ARRAY_COMPATIBILITY)
6354*6fee86a4SJeremy Kemp         }
6355*6fee86a4SJeremy Kemp 
6356*6fee86a4SJeremy Kemp         object_ = ::clCreateProgramWithSource(
6357*6fee86a4SJeremy Kemp             context(), (cl_uint)n, strings.data(), lengths.data(), &error);
6358*6fee86a4SJeremy Kemp 
6359*6fee86a4SJeremy Kemp         detail::errHandler(error, __CREATE_PROGRAM_WITH_SOURCE_ERR);
6360*6fee86a4SJeremy Kemp         if (err != nullptr) {
6361*6fee86a4SJeremy Kemp             *err = error;
6362*6fee86a4SJeremy Kemp         }
6363*6fee86a4SJeremy Kemp     }
6364*6fee86a4SJeremy Kemp 
6365*6fee86a4SJeremy Kemp     /**
6366*6fee86a4SJeremy Kemp      * Create a program from a vector of source strings and a provided context.
6367*6fee86a4SJeremy Kemp      * Does not compile or link the program.
6368*6fee86a4SJeremy Kemp      */
Program(const Context & context,const Sources & sources,cl_int * err=nullptr)6369*6fee86a4SJeremy Kemp     Program(
6370*6fee86a4SJeremy Kemp         const Context& context,
6371*6fee86a4SJeremy Kemp         const Sources& sources,
6372*6fee86a4SJeremy Kemp         cl_int* err = nullptr)
6373*6fee86a4SJeremy Kemp     {
6374*6fee86a4SJeremy Kemp         cl_int error;
6375*6fee86a4SJeremy Kemp 
6376*6fee86a4SJeremy Kemp         const size_type n = (size_type)sources.size();
6377*6fee86a4SJeremy Kemp 
6378*6fee86a4SJeremy Kemp         vector<size_type> lengths(n);
6379*6fee86a4SJeremy Kemp         vector<const char*> strings(n);
6380*6fee86a4SJeremy Kemp 
6381*6fee86a4SJeremy Kemp         for (size_type i = 0; i < n; ++i) {
6382*6fee86a4SJeremy Kemp #if !defined(CL_HPP_ENABLE_PROGRAM_CONSTRUCTION_FROM_ARRAY_COMPATIBILITY)
6383*6fee86a4SJeremy Kemp             strings[i] = sources[(int)i].data();
6384*6fee86a4SJeremy Kemp             lengths[i] = sources[(int)i].length();
6385*6fee86a4SJeremy Kemp #else // #if !defined(CL_HPP_ENABLE_PROGRAM_CONSTRUCTION_FROM_ARRAY_COMPATIBILITY)
6386*6fee86a4SJeremy Kemp             strings[i] = sources[(int)i].first;
6387*6fee86a4SJeremy Kemp             lengths[i] = sources[(int)i].second;
6388*6fee86a4SJeremy Kemp #endif // #if !defined(CL_HPP_ENABLE_PROGRAM_CONSTRUCTION_FROM_ARRAY_COMPATIBILITY)
6389*6fee86a4SJeremy Kemp         }
6390*6fee86a4SJeremy Kemp 
6391*6fee86a4SJeremy Kemp         object_ = ::clCreateProgramWithSource(
6392*6fee86a4SJeremy Kemp             context(), (cl_uint)n, strings.data(), lengths.data(), &error);
6393*6fee86a4SJeremy Kemp 
6394*6fee86a4SJeremy Kemp         detail::errHandler(error, __CREATE_PROGRAM_WITH_SOURCE_ERR);
6395*6fee86a4SJeremy Kemp         if (err != nullptr) {
6396*6fee86a4SJeremy Kemp             *err = error;
6397*6fee86a4SJeremy Kemp         }
6398*6fee86a4SJeremy Kemp     }
6399*6fee86a4SJeremy Kemp 
6400*6fee86a4SJeremy Kemp 
6401*6fee86a4SJeremy Kemp #if defined(CL_HPP_USE_IL_KHR) || CL_HPP_TARGET_OPENCL_VERSION >= 210
6402*6fee86a4SJeremy Kemp     /**
6403*6fee86a4SJeremy Kemp      * Program constructor to allow construction of program from SPIR-V or another IL.
6404*6fee86a4SJeremy Kemp      *
6405*6fee86a4SJeremy Kemp      * Requires OpenCL 2.1 or newer or the cl_khr_il_program extension.
6406*6fee86a4SJeremy Kemp      */
Program(const vector<char> & IL,bool build=false,cl_int * err=nullptr)6407*6fee86a4SJeremy Kemp     Program(
6408*6fee86a4SJeremy Kemp         const vector<char>& IL,
6409*6fee86a4SJeremy Kemp         bool build = false,
6410*6fee86a4SJeremy Kemp         cl_int* err = nullptr)
6411*6fee86a4SJeremy Kemp     {
6412*6fee86a4SJeremy Kemp         cl_int error;
6413*6fee86a4SJeremy Kemp 
6414*6fee86a4SJeremy Kemp         Context context = Context::getDefault(err);
6415*6fee86a4SJeremy Kemp 
6416*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 210
6417*6fee86a4SJeremy Kemp 
6418*6fee86a4SJeremy Kemp         object_ = ::clCreateProgramWithIL(
6419*6fee86a4SJeremy Kemp             context(), static_cast<const void*>(IL.data()), IL.size(), &error);
6420*6fee86a4SJeremy Kemp 
6421*6fee86a4SJeremy Kemp #else // #if CL_HPP_TARGET_OPENCL_VERSION >= 210
6422*6fee86a4SJeremy Kemp 
6423*6fee86a4SJeremy Kemp         typedef clCreateProgramWithILKHR_fn PFN_clCreateProgramWithILKHR;
6424*6fee86a4SJeremy Kemp         static PFN_clCreateProgramWithILKHR pfn_clCreateProgramWithILKHR = nullptr;
6425*6fee86a4SJeremy Kemp         CL_HPP_INIT_CL_EXT_FCN_PTR_(clCreateProgramWithILKHR);
6426*6fee86a4SJeremy Kemp 
6427*6fee86a4SJeremy Kemp         object_ = pfn_clCreateProgramWithILKHR(
6428*6fee86a4SJeremy Kemp                 context(), static_cast<const void*>(IL.data()), IL.size(), &error);
6429*6fee86a4SJeremy Kemp 
6430*6fee86a4SJeremy Kemp #endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 210
6431*6fee86a4SJeremy Kemp 
6432*6fee86a4SJeremy Kemp         detail::errHandler(error, __CREATE_PROGRAM_WITH_IL_ERR);
6433*6fee86a4SJeremy Kemp 
6434*6fee86a4SJeremy Kemp         if (error == CL_SUCCESS && build) {
6435*6fee86a4SJeremy Kemp 
6436*6fee86a4SJeremy Kemp             error = ::clBuildProgram(
6437*6fee86a4SJeremy Kemp                 object_,
6438*6fee86a4SJeremy Kemp                 0,
6439*6fee86a4SJeremy Kemp                 nullptr,
6440*6fee86a4SJeremy Kemp #if !defined(CL_HPP_CL_1_2_DEFAULT_BUILD)
6441*6fee86a4SJeremy Kemp                 "-cl-std=CL2.0",
6442*6fee86a4SJeremy Kemp #else
6443*6fee86a4SJeremy Kemp                 "",
6444*6fee86a4SJeremy Kemp #endif // #if !defined(CL_HPP_CL_1_2_DEFAULT_BUILD)
6445*6fee86a4SJeremy Kemp                 nullptr,
6446*6fee86a4SJeremy Kemp                 nullptr);
6447*6fee86a4SJeremy Kemp 
6448*6fee86a4SJeremy Kemp             detail::buildErrHandler(error, __BUILD_PROGRAM_ERR, getBuildInfo<CL_PROGRAM_BUILD_LOG>());
6449*6fee86a4SJeremy Kemp         }
6450*6fee86a4SJeremy Kemp 
6451*6fee86a4SJeremy Kemp         if (err != nullptr) {
6452*6fee86a4SJeremy Kemp             *err = error;
6453*6fee86a4SJeremy Kemp         }
6454*6fee86a4SJeremy Kemp     }
6455*6fee86a4SJeremy Kemp 
6456*6fee86a4SJeremy Kemp     /**
6457*6fee86a4SJeremy Kemp      * Program constructor to allow construction of program from SPIR-V or another IL
6458*6fee86a4SJeremy Kemp      * for a specific context.
6459*6fee86a4SJeremy Kemp      *
6460*6fee86a4SJeremy Kemp      * Requires OpenCL 2.1 or newer or the cl_khr_il_program extension.
6461*6fee86a4SJeremy Kemp      */
Program(const Context & context,const vector<char> & IL,bool build=false,cl_int * err=nullptr)6462*6fee86a4SJeremy Kemp     Program(
6463*6fee86a4SJeremy Kemp         const Context& context,
6464*6fee86a4SJeremy Kemp         const vector<char>& IL,
6465*6fee86a4SJeremy Kemp         bool build = false,
6466*6fee86a4SJeremy Kemp         cl_int* err = nullptr)
6467*6fee86a4SJeremy Kemp     {
6468*6fee86a4SJeremy Kemp         cl_int error;
6469*6fee86a4SJeremy Kemp 
6470*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 210
6471*6fee86a4SJeremy Kemp 
6472*6fee86a4SJeremy Kemp         object_ = ::clCreateProgramWithIL(
6473*6fee86a4SJeremy Kemp             context(), static_cast<const void*>(IL.data()), IL.size(), &error);
6474*6fee86a4SJeremy Kemp 
6475*6fee86a4SJeremy Kemp #else // #if CL_HPP_TARGET_OPENCL_VERSION >= 210
6476*6fee86a4SJeremy Kemp 
6477*6fee86a4SJeremy Kemp         typedef clCreateProgramWithILKHR_fn PFN_clCreateProgramWithILKHR;
6478*6fee86a4SJeremy Kemp         static PFN_clCreateProgramWithILKHR pfn_clCreateProgramWithILKHR = nullptr;
6479*6fee86a4SJeremy Kemp         CL_HPP_INIT_CL_EXT_FCN_PTR_(clCreateProgramWithILKHR);
6480*6fee86a4SJeremy Kemp 
6481*6fee86a4SJeremy Kemp         object_ = pfn_clCreateProgramWithILKHR(
6482*6fee86a4SJeremy Kemp             context(), static_cast<const void*>(IL.data()), IL.size(), &error);
6483*6fee86a4SJeremy Kemp 
6484*6fee86a4SJeremy Kemp #endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 210
6485*6fee86a4SJeremy Kemp 
6486*6fee86a4SJeremy Kemp         detail::errHandler(error, __CREATE_PROGRAM_WITH_IL_ERR);
6487*6fee86a4SJeremy Kemp 
6488*6fee86a4SJeremy Kemp         if (error == CL_SUCCESS && build) {
6489*6fee86a4SJeremy Kemp             error = ::clBuildProgram(
6490*6fee86a4SJeremy Kemp                 object_,
6491*6fee86a4SJeremy Kemp                 0,
6492*6fee86a4SJeremy Kemp                 nullptr,
6493*6fee86a4SJeremy Kemp #if !defined(CL_HPP_CL_1_2_DEFAULT_BUILD)
6494*6fee86a4SJeremy Kemp                 "-cl-std=CL2.0",
6495*6fee86a4SJeremy Kemp #else
6496*6fee86a4SJeremy Kemp                 "",
6497*6fee86a4SJeremy Kemp #endif // #if !defined(CL_HPP_CL_1_2_DEFAULT_BUILD)
6498*6fee86a4SJeremy Kemp                 nullptr,
6499*6fee86a4SJeremy Kemp                 nullptr);
6500*6fee86a4SJeremy Kemp 
6501*6fee86a4SJeremy Kemp             detail::buildErrHandler(error, __BUILD_PROGRAM_ERR, getBuildInfo<CL_PROGRAM_BUILD_LOG>());
6502*6fee86a4SJeremy Kemp         }
6503*6fee86a4SJeremy Kemp 
6504*6fee86a4SJeremy Kemp         if (err != nullptr) {
6505*6fee86a4SJeremy Kemp             *err = error;
6506*6fee86a4SJeremy Kemp         }
6507*6fee86a4SJeremy Kemp     }
6508*6fee86a4SJeremy Kemp #endif // defined(CL_HPP_USE_IL_KHR) || CL_HPP_TARGET_OPENCL_VERSION >= 210
6509*6fee86a4SJeremy Kemp 
6510*6fee86a4SJeremy Kemp     /**
6511*6fee86a4SJeremy Kemp      * Construct a program object from a list of devices and a per-device list of binaries.
6512*6fee86a4SJeremy Kemp      * \param context A valid OpenCL context in which to construct the program.
6513*6fee86a4SJeremy Kemp      * \param devices A vector of OpenCL device objects for which the program will be created.
6514*6fee86a4SJeremy Kemp      * \param binaries A vector of pairs of a pointer to a binary object and its length.
6515*6fee86a4SJeremy Kemp      * \param binaryStatus An optional vector that on completion will be resized to
6516*6fee86a4SJeremy Kemp      *   match the size of binaries and filled with values to specify if each binary
6517*6fee86a4SJeremy Kemp      *   was successfully loaded.
6518*6fee86a4SJeremy Kemp      *   Set to CL_SUCCESS if the binary was successfully loaded.
6519*6fee86a4SJeremy Kemp      *   Set to CL_INVALID_VALUE if the length is 0 or the binary pointer is nullptr.
6520*6fee86a4SJeremy Kemp      *   Set to CL_INVALID_BINARY if the binary provided is not valid for the matching device.
6521*6fee86a4SJeremy Kemp      * \param err if non-nullptr will be set to CL_SUCCESS on successful operation or one of the following errors:
6522*6fee86a4SJeremy Kemp      *   CL_INVALID_CONTEXT if context is not a valid context.
6523*6fee86a4SJeremy Kemp      *   CL_INVALID_VALUE if the length of devices is zero; or if the length of binaries does not match the length of devices;
6524*6fee86a4SJeremy Kemp      *     or if any entry in binaries is nullptr or has length 0.
6525*6fee86a4SJeremy Kemp      *   CL_INVALID_DEVICE if OpenCL devices listed in devices are not in the list of devices associated with context.
6526*6fee86a4SJeremy Kemp      *   CL_INVALID_BINARY if an invalid program binary was encountered for any device. binaryStatus will return specific status for each device.
6527*6fee86a4SJeremy Kemp      *   CL_OUT_OF_HOST_MEMORY if there is a failure to allocate resources required by the OpenCL implementation on the host.
6528*6fee86a4SJeremy Kemp      */
Program(const Context & context,const vector<Device> & devices,const Binaries & binaries,vector<cl_int> * binaryStatus=nullptr,cl_int * err=nullptr)6529*6fee86a4SJeremy Kemp     Program(
6530*6fee86a4SJeremy Kemp         const Context& context,
6531*6fee86a4SJeremy Kemp         const vector<Device>& devices,
6532*6fee86a4SJeremy Kemp         const Binaries& binaries,
6533*6fee86a4SJeremy Kemp         vector<cl_int>* binaryStatus = nullptr,
6534*6fee86a4SJeremy Kemp         cl_int* err = nullptr)
6535*6fee86a4SJeremy Kemp     {
6536*6fee86a4SJeremy Kemp         cl_int error;
6537*6fee86a4SJeremy Kemp 
6538*6fee86a4SJeremy Kemp         const size_type numDevices = devices.size();
6539*6fee86a4SJeremy Kemp 
6540*6fee86a4SJeremy Kemp         // Catch size mismatch early and return
6541*6fee86a4SJeremy Kemp         if(binaries.size() != numDevices) {
6542*6fee86a4SJeremy Kemp             error = CL_INVALID_VALUE;
6543*6fee86a4SJeremy Kemp             detail::errHandler(error, __CREATE_PROGRAM_WITH_BINARY_ERR);
6544*6fee86a4SJeremy Kemp             if (err != nullptr) {
6545*6fee86a4SJeremy Kemp                 *err = error;
6546*6fee86a4SJeremy Kemp             }
6547*6fee86a4SJeremy Kemp             return;
6548*6fee86a4SJeremy Kemp         }
6549*6fee86a4SJeremy Kemp 
6550*6fee86a4SJeremy Kemp 
6551*6fee86a4SJeremy Kemp         vector<size_type> lengths(numDevices);
6552*6fee86a4SJeremy Kemp         vector<const unsigned char*> images(numDevices);
6553*6fee86a4SJeremy Kemp #if !defined(CL_HPP_ENABLE_PROGRAM_CONSTRUCTION_FROM_ARRAY_COMPATIBILITY)
6554*6fee86a4SJeremy Kemp         for (size_type i = 0; i < numDevices; ++i) {
6555*6fee86a4SJeremy Kemp             images[i] = binaries[i].data();
6556*6fee86a4SJeremy Kemp             lengths[i] = binaries[(int)i].size();
6557*6fee86a4SJeremy Kemp         }
6558*6fee86a4SJeremy Kemp #else // #if !defined(CL_HPP_ENABLE_PROGRAM_CONSTRUCTION_FROM_ARRAY_COMPATIBILITY)
6559*6fee86a4SJeremy Kemp         for (size_type i = 0; i < numDevices; ++i) {
6560*6fee86a4SJeremy Kemp             images[i] = (const unsigned char*)binaries[i].first;
6561*6fee86a4SJeremy Kemp             lengths[i] = binaries[(int)i].second;
6562*6fee86a4SJeremy Kemp         }
6563*6fee86a4SJeremy Kemp #endif // #if !defined(CL_HPP_ENABLE_PROGRAM_CONSTRUCTION_FROM_ARRAY_COMPATIBILITY)
6564*6fee86a4SJeremy Kemp 
6565*6fee86a4SJeremy Kemp         vector<cl_device_id> deviceIDs(numDevices);
6566*6fee86a4SJeremy Kemp         for( size_type deviceIndex = 0; deviceIndex < numDevices; ++deviceIndex ) {
6567*6fee86a4SJeremy Kemp             deviceIDs[deviceIndex] = (devices[deviceIndex])();
6568*6fee86a4SJeremy Kemp         }
6569*6fee86a4SJeremy Kemp 
6570*6fee86a4SJeremy Kemp         if(binaryStatus) {
6571*6fee86a4SJeremy Kemp             binaryStatus->resize(numDevices);
6572*6fee86a4SJeremy Kemp         }
6573*6fee86a4SJeremy Kemp 
6574*6fee86a4SJeremy Kemp         object_ = ::clCreateProgramWithBinary(
6575*6fee86a4SJeremy Kemp             context(), (cl_uint) devices.size(),
6576*6fee86a4SJeremy Kemp             deviceIDs.data(),
6577*6fee86a4SJeremy Kemp             lengths.data(), images.data(), (binaryStatus != nullptr && numDevices > 0)
6578*6fee86a4SJeremy Kemp                ? &binaryStatus->front()
6579*6fee86a4SJeremy Kemp                : nullptr, &error);
6580*6fee86a4SJeremy Kemp 
6581*6fee86a4SJeremy Kemp         detail::errHandler(error, __CREATE_PROGRAM_WITH_BINARY_ERR);
6582*6fee86a4SJeremy Kemp         if (err != nullptr) {
6583*6fee86a4SJeremy Kemp             *err = error;
6584*6fee86a4SJeremy Kemp         }
6585*6fee86a4SJeremy Kemp     }
6586*6fee86a4SJeremy Kemp 
6587*6fee86a4SJeremy Kemp 
6588*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 120
6589*6fee86a4SJeremy Kemp     /**
6590*6fee86a4SJeremy Kemp      * Create program using builtin kernels.
6591*6fee86a4SJeremy Kemp      * \param kernelNames Semi-colon separated list of builtin kernel names
6592*6fee86a4SJeremy Kemp      */
Program(const Context & context,const vector<Device> & devices,const string & kernelNames,cl_int * err=nullptr)6593*6fee86a4SJeremy Kemp     Program(
6594*6fee86a4SJeremy Kemp         const Context& context,
6595*6fee86a4SJeremy Kemp         const vector<Device>& devices,
6596*6fee86a4SJeremy Kemp         const string& kernelNames,
6597*6fee86a4SJeremy Kemp         cl_int* err = nullptr)
6598*6fee86a4SJeremy Kemp     {
6599*6fee86a4SJeremy Kemp         cl_int error;
6600*6fee86a4SJeremy Kemp 
6601*6fee86a4SJeremy Kemp 
6602*6fee86a4SJeremy Kemp         size_type numDevices = devices.size();
6603*6fee86a4SJeremy Kemp         vector<cl_device_id> deviceIDs(numDevices);
6604*6fee86a4SJeremy Kemp         for( size_type deviceIndex = 0; deviceIndex < numDevices; ++deviceIndex ) {
6605*6fee86a4SJeremy Kemp             deviceIDs[deviceIndex] = (devices[deviceIndex])();
6606*6fee86a4SJeremy Kemp         }
6607*6fee86a4SJeremy Kemp 
6608*6fee86a4SJeremy Kemp         object_ = ::clCreateProgramWithBuiltInKernels(
6609*6fee86a4SJeremy Kemp             context(),
6610*6fee86a4SJeremy Kemp             (cl_uint) devices.size(),
6611*6fee86a4SJeremy Kemp             deviceIDs.data(),
6612*6fee86a4SJeremy Kemp             kernelNames.c_str(),
6613*6fee86a4SJeremy Kemp             &error);
6614*6fee86a4SJeremy Kemp 
6615*6fee86a4SJeremy Kemp         detail::errHandler(error, __CREATE_PROGRAM_WITH_BUILT_IN_KERNELS_ERR);
6616*6fee86a4SJeremy Kemp         if (err != nullptr) {
6617*6fee86a4SJeremy Kemp             *err = error;
6618*6fee86a4SJeremy Kemp         }
6619*6fee86a4SJeremy Kemp     }
6620*6fee86a4SJeremy Kemp #endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
6621*6fee86a4SJeremy Kemp 
Program()6622*6fee86a4SJeremy Kemp     Program() { }
6623*6fee86a4SJeremy Kemp 
6624*6fee86a4SJeremy Kemp 
6625*6fee86a4SJeremy Kemp     /*! \brief Constructor from cl_program - takes ownership.
6626*6fee86a4SJeremy Kemp      *
6627*6fee86a4SJeremy Kemp      * \param retainObject will cause the constructor to retain its cl object.
6628*6fee86a4SJeremy Kemp      *                     Defaults to false to maintain compatibility with
6629*6fee86a4SJeremy Kemp      *                     earlier versions.
6630*6fee86a4SJeremy Kemp      */
Program(const cl_program & program,bool retainObject=false)6631*6fee86a4SJeremy Kemp     explicit Program(const cl_program& program, bool retainObject = false) :
6632*6fee86a4SJeremy Kemp         detail::Wrapper<cl_type>(program, retainObject) { }
6633*6fee86a4SJeremy Kemp 
operator =(const cl_program & rhs)6634*6fee86a4SJeremy Kemp     Program& operator = (const cl_program& rhs)
6635*6fee86a4SJeremy Kemp     {
6636*6fee86a4SJeremy Kemp         detail::Wrapper<cl_type>::operator=(rhs);
6637*6fee86a4SJeremy Kemp         return *this;
6638*6fee86a4SJeremy Kemp     }
6639*6fee86a4SJeremy Kemp 
6640*6fee86a4SJeremy Kemp 
build(const vector<Device> & devices,const char * options=nullptr,void (CL_CALLBACK * notifyFptr)(cl_program,void *)=nullptr,void * data=nullptr) const6641*6fee86a4SJeremy Kemp     cl_int build(
6642*6fee86a4SJeremy Kemp         const vector<Device>& devices,
6643*6fee86a4SJeremy Kemp         const char* options = nullptr,
6644*6fee86a4SJeremy Kemp         void (CL_CALLBACK * notifyFptr)(cl_program, void *) = nullptr,
6645*6fee86a4SJeremy Kemp         void* data = nullptr) const
6646*6fee86a4SJeremy Kemp     {
6647*6fee86a4SJeremy Kemp         size_type numDevices = devices.size();
6648*6fee86a4SJeremy Kemp         vector<cl_device_id> deviceIDs(numDevices);
6649*6fee86a4SJeremy Kemp 
6650*6fee86a4SJeremy Kemp         for( size_type deviceIndex = 0; deviceIndex < numDevices; ++deviceIndex ) {
6651*6fee86a4SJeremy Kemp             deviceIDs[deviceIndex] = (devices[deviceIndex])();
6652*6fee86a4SJeremy Kemp         }
6653*6fee86a4SJeremy Kemp 
6654*6fee86a4SJeremy Kemp         cl_int buildError = ::clBuildProgram(
6655*6fee86a4SJeremy Kemp             object_,
6656*6fee86a4SJeremy Kemp             (cl_uint)
6657*6fee86a4SJeremy Kemp             devices.size(),
6658*6fee86a4SJeremy Kemp             deviceIDs.data(),
6659*6fee86a4SJeremy Kemp             options,
6660*6fee86a4SJeremy Kemp             notifyFptr,
6661*6fee86a4SJeremy Kemp             data);
6662*6fee86a4SJeremy Kemp 
6663*6fee86a4SJeremy Kemp         return detail::buildErrHandler(buildError, __BUILD_PROGRAM_ERR, getBuildInfo<CL_PROGRAM_BUILD_LOG>());
6664*6fee86a4SJeremy Kemp     }
6665*6fee86a4SJeremy Kemp 
build(const Device & device,const char * options=nullptr,void (CL_CALLBACK * notifyFptr)(cl_program,void *)=nullptr,void * data=nullptr) const6666*6fee86a4SJeremy Kemp     cl_int build(
6667*6fee86a4SJeremy Kemp         const Device& device,
6668*6fee86a4SJeremy Kemp         const char* options = nullptr,
6669*6fee86a4SJeremy Kemp         void (CL_CALLBACK * notifyFptr)(cl_program, void *) = nullptr,
6670*6fee86a4SJeremy Kemp         void* data = nullptr) const
6671*6fee86a4SJeremy Kemp     {
6672*6fee86a4SJeremy Kemp         cl_device_id deviceID = device();
6673*6fee86a4SJeremy Kemp 
6674*6fee86a4SJeremy Kemp         cl_int buildError = ::clBuildProgram(
6675*6fee86a4SJeremy Kemp             object_,
6676*6fee86a4SJeremy Kemp             1,
6677*6fee86a4SJeremy Kemp             &deviceID,
6678*6fee86a4SJeremy Kemp             options,
6679*6fee86a4SJeremy Kemp             notifyFptr,
6680*6fee86a4SJeremy Kemp             data);
6681*6fee86a4SJeremy Kemp 
6682*6fee86a4SJeremy Kemp         BuildLogType buildLog(0);
6683*6fee86a4SJeremy Kemp         buildLog.push_back(std::make_pair(device, getBuildInfo<CL_PROGRAM_BUILD_LOG>(device)));
6684*6fee86a4SJeremy Kemp         return detail::buildErrHandler(buildError, __BUILD_PROGRAM_ERR, buildLog);
6685*6fee86a4SJeremy Kemp     }
6686*6fee86a4SJeremy Kemp 
build(const char * options=nullptr,void (CL_CALLBACK * notifyFptr)(cl_program,void *)=nullptr,void * data=nullptr) const6687*6fee86a4SJeremy Kemp     cl_int build(
6688*6fee86a4SJeremy Kemp         const char* options = nullptr,
6689*6fee86a4SJeremy Kemp         void (CL_CALLBACK * notifyFptr)(cl_program, void *) = nullptr,
6690*6fee86a4SJeremy Kemp         void* data = nullptr) const
6691*6fee86a4SJeremy Kemp     {
6692*6fee86a4SJeremy Kemp         cl_int buildError = ::clBuildProgram(
6693*6fee86a4SJeremy Kemp             object_,
6694*6fee86a4SJeremy Kemp             0,
6695*6fee86a4SJeremy Kemp             nullptr,
6696*6fee86a4SJeremy Kemp             options,
6697*6fee86a4SJeremy Kemp             notifyFptr,
6698*6fee86a4SJeremy Kemp             data);
6699*6fee86a4SJeremy Kemp 
6700*6fee86a4SJeremy Kemp         return detail::buildErrHandler(buildError, __BUILD_PROGRAM_ERR, getBuildInfo<CL_PROGRAM_BUILD_LOG>());
6701*6fee86a4SJeremy Kemp     }
6702*6fee86a4SJeremy Kemp 
6703*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 120
compile(const char * options=nullptr,void (CL_CALLBACK * notifyFptr)(cl_program,void *)=nullptr,void * data=nullptr) const6704*6fee86a4SJeremy Kemp     cl_int compile(
6705*6fee86a4SJeremy Kemp         const char* options = nullptr,
6706*6fee86a4SJeremy Kemp         void (CL_CALLBACK * notifyFptr)(cl_program, void *) = nullptr,
6707*6fee86a4SJeremy Kemp         void* data = nullptr) const
6708*6fee86a4SJeremy Kemp     {
6709*6fee86a4SJeremy Kemp         cl_int error = ::clCompileProgram(
6710*6fee86a4SJeremy Kemp             object_,
6711*6fee86a4SJeremy Kemp             0,
6712*6fee86a4SJeremy Kemp             nullptr,
6713*6fee86a4SJeremy Kemp             options,
6714*6fee86a4SJeremy Kemp             0,
6715*6fee86a4SJeremy Kemp             nullptr,
6716*6fee86a4SJeremy Kemp             nullptr,
6717*6fee86a4SJeremy Kemp             notifyFptr,
6718*6fee86a4SJeremy Kemp             data);
6719*6fee86a4SJeremy Kemp         return detail::buildErrHandler(error, __COMPILE_PROGRAM_ERR, getBuildInfo<CL_PROGRAM_BUILD_LOG>());
6720*6fee86a4SJeremy Kemp     }
6721*6fee86a4SJeremy Kemp #endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
6722*6fee86a4SJeremy Kemp 
6723*6fee86a4SJeremy Kemp     template <typename T>
getInfo(cl_program_info name,T * param) const6724*6fee86a4SJeremy Kemp     cl_int getInfo(cl_program_info name, T* param) const
6725*6fee86a4SJeremy Kemp     {
6726*6fee86a4SJeremy Kemp         return detail::errHandler(
6727*6fee86a4SJeremy Kemp             detail::getInfo(&::clGetProgramInfo, object_, name, param),
6728*6fee86a4SJeremy Kemp             __GET_PROGRAM_INFO_ERR);
6729*6fee86a4SJeremy Kemp     }
6730*6fee86a4SJeremy Kemp 
6731*6fee86a4SJeremy Kemp     template <cl_program_info name> typename
6732*6fee86a4SJeremy Kemp     detail::param_traits<detail::cl_program_info, name>::param_type
getInfo(cl_int * err=nullptr) const6733*6fee86a4SJeremy Kemp     getInfo(cl_int* err = nullptr) const
6734*6fee86a4SJeremy Kemp     {
6735*6fee86a4SJeremy Kemp         typename detail::param_traits<
6736*6fee86a4SJeremy Kemp             detail::cl_program_info, name>::param_type param;
6737*6fee86a4SJeremy Kemp         cl_int result = getInfo(name, &param);
6738*6fee86a4SJeremy Kemp         if (err != nullptr) {
6739*6fee86a4SJeremy Kemp             *err = result;
6740*6fee86a4SJeremy Kemp         }
6741*6fee86a4SJeremy Kemp         return param;
6742*6fee86a4SJeremy Kemp     }
6743*6fee86a4SJeremy Kemp 
6744*6fee86a4SJeremy Kemp     template <typename T>
getBuildInfo(const Device & device,cl_program_build_info name,T * param) const6745*6fee86a4SJeremy Kemp     cl_int getBuildInfo(
6746*6fee86a4SJeremy Kemp         const Device& device, cl_program_build_info name, T* param) const
6747*6fee86a4SJeremy Kemp     {
6748*6fee86a4SJeremy Kemp         return detail::errHandler(
6749*6fee86a4SJeremy Kemp             detail::getInfo(
6750*6fee86a4SJeremy Kemp                 &::clGetProgramBuildInfo, object_, device(), name, param),
6751*6fee86a4SJeremy Kemp                 __GET_PROGRAM_BUILD_INFO_ERR);
6752*6fee86a4SJeremy Kemp     }
6753*6fee86a4SJeremy Kemp 
6754*6fee86a4SJeremy Kemp     template <cl_program_build_info name> typename
6755*6fee86a4SJeremy Kemp     detail::param_traits<detail::cl_program_build_info, name>::param_type
getBuildInfo(const Device & device,cl_int * err=nullptr) const6756*6fee86a4SJeremy Kemp     getBuildInfo(const Device& device, cl_int* err = nullptr) const
6757*6fee86a4SJeremy Kemp     {
6758*6fee86a4SJeremy Kemp         typename detail::param_traits<
6759*6fee86a4SJeremy Kemp             detail::cl_program_build_info, name>::param_type param;
6760*6fee86a4SJeremy Kemp         cl_int result = getBuildInfo(device, name, &param);
6761*6fee86a4SJeremy Kemp         if (err != nullptr) {
6762*6fee86a4SJeremy Kemp             *err = result;
6763*6fee86a4SJeremy Kemp         }
6764*6fee86a4SJeremy Kemp         return param;
6765*6fee86a4SJeremy Kemp     }
6766*6fee86a4SJeremy Kemp 
6767*6fee86a4SJeremy Kemp     /**
6768*6fee86a4SJeremy Kemp      * Build info function that returns a vector of device/info pairs for the specified
6769*6fee86a4SJeremy Kemp      * info type and for all devices in the program.
6770*6fee86a4SJeremy Kemp      * On an error reading the info for any device, an empty vector of info will be returned.
6771*6fee86a4SJeremy Kemp      */
6772*6fee86a4SJeremy Kemp     template <cl_program_build_info name>
6773*6fee86a4SJeremy Kemp     vector<std::pair<cl::Device, typename detail::param_traits<detail::cl_program_build_info, name>::param_type>>
getBuildInfo(cl_int * err=nullptr) const6774*6fee86a4SJeremy Kemp         getBuildInfo(cl_int *err = nullptr) const
6775*6fee86a4SJeremy Kemp     {
6776*6fee86a4SJeremy Kemp         cl_int result = CL_SUCCESS;
6777*6fee86a4SJeremy Kemp 
6778*6fee86a4SJeremy Kemp         auto devs = getInfo<CL_PROGRAM_DEVICES>(&result);
6779*6fee86a4SJeremy Kemp         vector<std::pair<cl::Device, typename detail::param_traits<detail::cl_program_build_info, name>::param_type>>
6780*6fee86a4SJeremy Kemp             devInfo;
6781*6fee86a4SJeremy Kemp 
6782*6fee86a4SJeremy Kemp         // If there was an initial error from getInfo return the error
6783*6fee86a4SJeremy Kemp         if (result != CL_SUCCESS) {
6784*6fee86a4SJeremy Kemp             if (err != nullptr) {
6785*6fee86a4SJeremy Kemp                 *err = result;
6786*6fee86a4SJeremy Kemp             }
6787*6fee86a4SJeremy Kemp             return devInfo;
6788*6fee86a4SJeremy Kemp         }
6789*6fee86a4SJeremy Kemp 
6790*6fee86a4SJeremy Kemp         for (const cl::Device &d : devs) {
6791*6fee86a4SJeremy Kemp             typename detail::param_traits<
6792*6fee86a4SJeremy Kemp                 detail::cl_program_build_info, name>::param_type param;
6793*6fee86a4SJeremy Kemp             result = getBuildInfo(d, name, &param);
6794*6fee86a4SJeremy Kemp             devInfo.push_back(
6795*6fee86a4SJeremy Kemp                 std::pair<cl::Device, typename detail::param_traits<detail::cl_program_build_info, name>::param_type>
6796*6fee86a4SJeremy Kemp                 (d, param));
6797*6fee86a4SJeremy Kemp             if (result != CL_SUCCESS) {
6798*6fee86a4SJeremy Kemp                 // On error, leave the loop and return the error code
6799*6fee86a4SJeremy Kemp                 break;
6800*6fee86a4SJeremy Kemp             }
6801*6fee86a4SJeremy Kemp         }
6802*6fee86a4SJeremy Kemp         if (err != nullptr) {
6803*6fee86a4SJeremy Kemp             *err = result;
6804*6fee86a4SJeremy Kemp         }
6805*6fee86a4SJeremy Kemp         if (result != CL_SUCCESS) {
6806*6fee86a4SJeremy Kemp             devInfo.clear();
6807*6fee86a4SJeremy Kemp         }
6808*6fee86a4SJeremy Kemp         return devInfo;
6809*6fee86a4SJeremy Kemp     }
6810*6fee86a4SJeremy Kemp 
createKernels(vector<Kernel> * kernels)6811*6fee86a4SJeremy Kemp     cl_int createKernels(vector<Kernel>* kernels)
6812*6fee86a4SJeremy Kemp     {
6813*6fee86a4SJeremy Kemp         cl_uint numKernels;
6814*6fee86a4SJeremy Kemp         cl_int err = ::clCreateKernelsInProgram(object_, 0, nullptr, &numKernels);
6815*6fee86a4SJeremy Kemp         if (err != CL_SUCCESS) {
6816*6fee86a4SJeremy Kemp             return detail::errHandler(err, __CREATE_KERNELS_IN_PROGRAM_ERR);
6817*6fee86a4SJeremy Kemp         }
6818*6fee86a4SJeremy Kemp 
6819*6fee86a4SJeremy Kemp         vector<cl_kernel> value(numKernels);
6820*6fee86a4SJeremy Kemp 
6821*6fee86a4SJeremy Kemp         err = ::clCreateKernelsInProgram(
6822*6fee86a4SJeremy Kemp             object_, numKernels, value.data(), nullptr);
6823*6fee86a4SJeremy Kemp         if (err != CL_SUCCESS) {
6824*6fee86a4SJeremy Kemp             return detail::errHandler(err, __CREATE_KERNELS_IN_PROGRAM_ERR);
6825*6fee86a4SJeremy Kemp         }
6826*6fee86a4SJeremy Kemp 
6827*6fee86a4SJeremy Kemp         if (kernels) {
6828*6fee86a4SJeremy Kemp             kernels->resize(value.size());
6829*6fee86a4SJeremy Kemp 
6830*6fee86a4SJeremy Kemp             // Assign to param, constructing with retain behaviour
6831*6fee86a4SJeremy Kemp             // to correctly capture each underlying CL object
6832*6fee86a4SJeremy Kemp             for (size_type i = 0; i < value.size(); i++) {
6833*6fee86a4SJeremy Kemp                 // We do not need to retain because this kernel is being created
6834*6fee86a4SJeremy Kemp                 // by the runtime
6835*6fee86a4SJeremy Kemp                 (*kernels)[i] = Kernel(value[i], false);
6836*6fee86a4SJeremy Kemp             }
6837*6fee86a4SJeremy Kemp         }
6838*6fee86a4SJeremy Kemp         return CL_SUCCESS;
6839*6fee86a4SJeremy Kemp     }
6840*6fee86a4SJeremy Kemp 
6841*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 220
6842*6fee86a4SJeremy Kemp #if defined(CL_USE_DEPRECATED_OPENCL_2_2_APIS)
6843*6fee86a4SJeremy Kemp     /*! \brief Registers a callback function to be called when destructors for
6844*6fee86a4SJeremy Kemp      *         program scope global variables are complete and before the
6845*6fee86a4SJeremy Kemp      *         program is released.
6846*6fee86a4SJeremy Kemp      *
6847*6fee86a4SJeremy Kemp      *  Wraps clSetProgramReleaseCallback().
6848*6fee86a4SJeremy Kemp      *
6849*6fee86a4SJeremy Kemp      *  Each call to this function registers the specified user callback function
6850*6fee86a4SJeremy Kemp      *  on a callback stack associated with program. The registered user callback
6851*6fee86a4SJeremy Kemp      *  functions are called in the reverse order in which they were registered.
6852*6fee86a4SJeremy Kemp      */
setReleaseCallback(void (CL_CALLBACK * pfn_notify)(cl_program program,void * user_data),void * user_data=nullptr)6853*6fee86a4SJeremy Kemp     CL_API_PREFIX__VERSION_2_2_DEPRECATED cl_int setReleaseCallback(
6854*6fee86a4SJeremy Kemp         void (CL_CALLBACK * pfn_notify)(cl_program program, void * user_data),
6855*6fee86a4SJeremy Kemp         void * user_data = nullptr) CL_API_SUFFIX__VERSION_2_2_DEPRECATED
6856*6fee86a4SJeremy Kemp     {
6857*6fee86a4SJeremy Kemp         return detail::errHandler(
6858*6fee86a4SJeremy Kemp             ::clSetProgramReleaseCallback(
6859*6fee86a4SJeremy Kemp                 object_,
6860*6fee86a4SJeremy Kemp                 pfn_notify,
6861*6fee86a4SJeremy Kemp                 user_data),
6862*6fee86a4SJeremy Kemp             __SET_PROGRAM_RELEASE_CALLBACK_ERR);
6863*6fee86a4SJeremy Kemp     }
6864*6fee86a4SJeremy Kemp #endif // #if defined(CL_USE_DEPRECATED_OPENCL_2_2_APIS)
6865*6fee86a4SJeremy Kemp 
6866*6fee86a4SJeremy Kemp     /*! \brief Sets a SPIR-V specialization constant.
6867*6fee86a4SJeremy Kemp      *
6868*6fee86a4SJeremy Kemp      *  Wraps clSetProgramSpecializationConstant().
6869*6fee86a4SJeremy Kemp      */
6870*6fee86a4SJeremy Kemp     template <typename T>
6871*6fee86a4SJeremy Kemp     typename std::enable_if<!std::is_pointer<T>::value, cl_int>::type
setSpecializationConstant(cl_uint index,const T & value)6872*6fee86a4SJeremy Kemp         setSpecializationConstant(cl_uint index, const T &value)
6873*6fee86a4SJeremy Kemp     {
6874*6fee86a4SJeremy Kemp         return detail::errHandler(
6875*6fee86a4SJeremy Kemp             ::clSetProgramSpecializationConstant(
6876*6fee86a4SJeremy Kemp                 object_,
6877*6fee86a4SJeremy Kemp                 index,
6878*6fee86a4SJeremy Kemp                 sizeof(value),
6879*6fee86a4SJeremy Kemp                 &value),
6880*6fee86a4SJeremy Kemp             __SET_PROGRAM_SPECIALIZATION_CONSTANT_ERR);
6881*6fee86a4SJeremy Kemp     }
6882*6fee86a4SJeremy Kemp 
6883*6fee86a4SJeremy Kemp     /*! \brief Sets a SPIR-V specialization constant.
6884*6fee86a4SJeremy Kemp      *
6885*6fee86a4SJeremy Kemp      *  Wraps clSetProgramSpecializationConstant().
6886*6fee86a4SJeremy Kemp      */
setSpecializationConstant(cl_uint index,size_type size,const void * value)6887*6fee86a4SJeremy Kemp     cl_int setSpecializationConstant(cl_uint index, size_type size, const void* value)
6888*6fee86a4SJeremy Kemp     {
6889*6fee86a4SJeremy Kemp         return detail::errHandler(
6890*6fee86a4SJeremy Kemp             ::clSetProgramSpecializationConstant(
6891*6fee86a4SJeremy Kemp                 object_,
6892*6fee86a4SJeremy Kemp                 index,
6893*6fee86a4SJeremy Kemp                 size,
6894*6fee86a4SJeremy Kemp                 value),
6895*6fee86a4SJeremy Kemp             __SET_PROGRAM_SPECIALIZATION_CONSTANT_ERR);
6896*6fee86a4SJeremy Kemp     }
6897*6fee86a4SJeremy Kemp #endif // CL_HPP_TARGET_OPENCL_VERSION >= 220
6898*6fee86a4SJeremy Kemp };
6899*6fee86a4SJeremy Kemp 
6900*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 120
linkProgram(const Program & input1,const Program & input2,const char * options=nullptr,void (CL_CALLBACK * notifyFptr)(cl_program,void *)=nullptr,void * data=nullptr,cl_int * err=nullptr)6901*6fee86a4SJeremy Kemp inline Program linkProgram(
6902*6fee86a4SJeremy Kemp     const Program& input1,
6903*6fee86a4SJeremy Kemp     const Program& input2,
6904*6fee86a4SJeremy Kemp     const char* options = nullptr,
6905*6fee86a4SJeremy Kemp     void (CL_CALLBACK * notifyFptr)(cl_program, void *) = nullptr,
6906*6fee86a4SJeremy Kemp     void* data = nullptr,
6907*6fee86a4SJeremy Kemp     cl_int* err = nullptr)
6908*6fee86a4SJeremy Kemp {
6909*6fee86a4SJeremy Kemp     cl_int error_local = CL_SUCCESS;
6910*6fee86a4SJeremy Kemp     cl_program programs[2] = { input1(), input2() };
6911*6fee86a4SJeremy Kemp 
6912*6fee86a4SJeremy Kemp     Context ctx = input1.getInfo<CL_PROGRAM_CONTEXT>(&error_local);
6913*6fee86a4SJeremy Kemp     if(error_local!=CL_SUCCESS) {
6914*6fee86a4SJeremy Kemp         detail::errHandler(error_local, __LINK_PROGRAM_ERR);
6915*6fee86a4SJeremy Kemp     }
6916*6fee86a4SJeremy Kemp 
6917*6fee86a4SJeremy Kemp     cl_program prog = ::clLinkProgram(
6918*6fee86a4SJeremy Kemp         ctx(),
6919*6fee86a4SJeremy Kemp         0,
6920*6fee86a4SJeremy Kemp         nullptr,
6921*6fee86a4SJeremy Kemp         options,
6922*6fee86a4SJeremy Kemp         2,
6923*6fee86a4SJeremy Kemp         programs,
6924*6fee86a4SJeremy Kemp         notifyFptr,
6925*6fee86a4SJeremy Kemp         data,
6926*6fee86a4SJeremy Kemp         &error_local);
6927*6fee86a4SJeremy Kemp 
6928*6fee86a4SJeremy Kemp     detail::errHandler(error_local,__COMPILE_PROGRAM_ERR);
6929*6fee86a4SJeremy Kemp     if (err != nullptr) {
6930*6fee86a4SJeremy Kemp         *err = error_local;
6931*6fee86a4SJeremy Kemp     }
6932*6fee86a4SJeremy Kemp 
6933*6fee86a4SJeremy Kemp     return Program(prog);
6934*6fee86a4SJeremy Kemp }
6935*6fee86a4SJeremy Kemp 
linkProgram(const vector<Program> & inputPrograms,const char * options=nullptr,void (CL_CALLBACK * notifyFptr)(cl_program,void *)=nullptr,void * data=nullptr,cl_int * err=nullptr)6936*6fee86a4SJeremy Kemp inline Program linkProgram(
6937*6fee86a4SJeremy Kemp     const vector<Program>& inputPrograms,
6938*6fee86a4SJeremy Kemp     const char* options = nullptr,
6939*6fee86a4SJeremy Kemp     void (CL_CALLBACK * notifyFptr)(cl_program, void *) = nullptr,
6940*6fee86a4SJeremy Kemp     void* data = nullptr,
6941*6fee86a4SJeremy Kemp     cl_int* err = nullptr)
6942*6fee86a4SJeremy Kemp {
6943*6fee86a4SJeremy Kemp     cl_int error_local = CL_SUCCESS;
6944*6fee86a4SJeremy Kemp     Context ctx;
6945*6fee86a4SJeremy Kemp 
6946*6fee86a4SJeremy Kemp     static_assert(sizeof(cl::Program) == sizeof(cl_program),
6947*6fee86a4SJeremy Kemp         "Size of cl::Program must be equal to size of cl_program");
6948*6fee86a4SJeremy Kemp 
6949*6fee86a4SJeremy Kemp     if(inputPrograms.size() > 0) {
6950*6fee86a4SJeremy Kemp         ctx = inputPrograms[0].getInfo<CL_PROGRAM_CONTEXT>(&error_local);
6951*6fee86a4SJeremy Kemp         if(error_local!=CL_SUCCESS) {
6952*6fee86a4SJeremy Kemp             detail::errHandler(error_local, __LINK_PROGRAM_ERR);
6953*6fee86a4SJeremy Kemp         }
6954*6fee86a4SJeremy Kemp     }
6955*6fee86a4SJeremy Kemp 
6956*6fee86a4SJeremy Kemp     cl_program prog = ::clLinkProgram(
6957*6fee86a4SJeremy Kemp         ctx(),
6958*6fee86a4SJeremy Kemp         0,
6959*6fee86a4SJeremy Kemp         nullptr,
6960*6fee86a4SJeremy Kemp         options,
6961*6fee86a4SJeremy Kemp         static_cast<cl_uint>(inputPrograms.size()),
6962*6fee86a4SJeremy Kemp         reinterpret_cast<const cl_program *>(inputPrograms.data()),
6963*6fee86a4SJeremy Kemp         notifyFptr,
6964*6fee86a4SJeremy Kemp         data,
6965*6fee86a4SJeremy Kemp         &error_local);
6966*6fee86a4SJeremy Kemp 
6967*6fee86a4SJeremy Kemp     detail::errHandler(error_local,__COMPILE_PROGRAM_ERR);
6968*6fee86a4SJeremy Kemp     if (err != nullptr) {
6969*6fee86a4SJeremy Kemp         *err = error_local;
6970*6fee86a4SJeremy Kemp     }
6971*6fee86a4SJeremy Kemp 
6972*6fee86a4SJeremy Kemp     return Program(prog);
6973*6fee86a4SJeremy Kemp }
6974*6fee86a4SJeremy Kemp #endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
6975*6fee86a4SJeremy Kemp 
6976*6fee86a4SJeremy Kemp // Template specialization for CL_PROGRAM_BINARIES
6977*6fee86a4SJeremy Kemp template <>
getInfo(cl_program_info name,vector<vector<unsigned char>> * param) const6978*6fee86a4SJeremy Kemp inline cl_int cl::Program::getInfo(cl_program_info name, vector<vector<unsigned char>>* param) const
6979*6fee86a4SJeremy Kemp {
6980*6fee86a4SJeremy Kemp     if (name != CL_PROGRAM_BINARIES) {
6981*6fee86a4SJeremy Kemp         return CL_INVALID_VALUE;
6982*6fee86a4SJeremy Kemp     }
6983*6fee86a4SJeremy Kemp     if (param) {
6984*6fee86a4SJeremy Kemp         // Resize the parameter array appropriately for each allocation
6985*6fee86a4SJeremy Kemp         // and pass down to the helper
6986*6fee86a4SJeremy Kemp 
6987*6fee86a4SJeremy Kemp         vector<size_type> sizes = getInfo<CL_PROGRAM_BINARY_SIZES>();
6988*6fee86a4SJeremy Kemp         size_type numBinaries = sizes.size();
6989*6fee86a4SJeremy Kemp 
6990*6fee86a4SJeremy Kemp         // Resize the parameter array and constituent arrays
6991*6fee86a4SJeremy Kemp         param->resize(numBinaries);
6992*6fee86a4SJeremy Kemp         for (size_type i = 0; i < numBinaries; ++i) {
6993*6fee86a4SJeremy Kemp             (*param)[i].resize(sizes[i]);
6994*6fee86a4SJeremy Kemp         }
6995*6fee86a4SJeremy Kemp 
6996*6fee86a4SJeremy Kemp         return detail::errHandler(
6997*6fee86a4SJeremy Kemp             detail::getInfo(&::clGetProgramInfo, object_, name, param),
6998*6fee86a4SJeremy Kemp             __GET_PROGRAM_INFO_ERR);
6999*6fee86a4SJeremy Kemp     }
7000*6fee86a4SJeremy Kemp 
7001*6fee86a4SJeremy Kemp     return CL_SUCCESS;
7002*6fee86a4SJeremy Kemp }
7003*6fee86a4SJeremy Kemp 
7004*6fee86a4SJeremy Kemp template<>
getInfo(cl_int * err) const7005*6fee86a4SJeremy Kemp inline vector<vector<unsigned char>> cl::Program::getInfo<CL_PROGRAM_BINARIES>(cl_int* err) const
7006*6fee86a4SJeremy Kemp {
7007*6fee86a4SJeremy Kemp     vector<vector<unsigned char>> binariesVectors;
7008*6fee86a4SJeremy Kemp 
7009*6fee86a4SJeremy Kemp     cl_int result = getInfo(CL_PROGRAM_BINARIES, &binariesVectors);
7010*6fee86a4SJeremy Kemp     if (err != nullptr) {
7011*6fee86a4SJeremy Kemp         *err = result;
7012*6fee86a4SJeremy Kemp     }
7013*6fee86a4SJeremy Kemp     return binariesVectors;
7014*6fee86a4SJeremy Kemp }
7015*6fee86a4SJeremy Kemp 
7016*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 220
7017*6fee86a4SJeremy Kemp // Template specialization for clSetProgramSpecializationConstant
7018*6fee86a4SJeremy Kemp template <>
setSpecializationConstant(cl_uint index,const bool & value)7019*6fee86a4SJeremy Kemp inline cl_int cl::Program::setSpecializationConstant(cl_uint index, const bool &value)
7020*6fee86a4SJeremy Kemp {
7021*6fee86a4SJeremy Kemp     cl_uchar ucValue = value ? CL_UCHAR_MAX : 0;
7022*6fee86a4SJeremy Kemp     return detail::errHandler(
7023*6fee86a4SJeremy Kemp         ::clSetProgramSpecializationConstant(
7024*6fee86a4SJeremy Kemp             object_,
7025*6fee86a4SJeremy Kemp             index,
7026*6fee86a4SJeremy Kemp             sizeof(ucValue),
7027*6fee86a4SJeremy Kemp             &ucValue),
7028*6fee86a4SJeremy Kemp         __SET_PROGRAM_SPECIALIZATION_CONSTANT_ERR);
7029*6fee86a4SJeremy Kemp }
7030*6fee86a4SJeremy Kemp #endif // CL_HPP_TARGET_OPENCL_VERSION >= 220
7031*6fee86a4SJeremy Kemp 
Kernel(const Program & program,const char * name,cl_int * err)7032*6fee86a4SJeremy Kemp inline Kernel::Kernel(const Program& program, const char* name, cl_int* err)
7033*6fee86a4SJeremy Kemp {
7034*6fee86a4SJeremy Kemp     cl_int error;
7035*6fee86a4SJeremy Kemp 
7036*6fee86a4SJeremy Kemp     object_ = ::clCreateKernel(program(), name, &error);
7037*6fee86a4SJeremy Kemp     detail::errHandler(error, __CREATE_KERNEL_ERR);
7038*6fee86a4SJeremy Kemp 
7039*6fee86a4SJeremy Kemp     if (err != nullptr) {
7040*6fee86a4SJeremy Kemp         *err = error;
7041*6fee86a4SJeremy Kemp     }
7042*6fee86a4SJeremy Kemp 
7043*6fee86a4SJeremy Kemp }
7044*6fee86a4SJeremy Kemp 
7045*6fee86a4SJeremy Kemp #ifdef cl_khr_external_memory
7046*6fee86a4SJeremy Kemp enum class ExternalMemoryType : cl_external_memory_handle_type_khr
7047*6fee86a4SJeremy Kemp {
7048*6fee86a4SJeremy Kemp     None = 0,
7049*6fee86a4SJeremy Kemp 
7050*6fee86a4SJeremy Kemp     OpaqueFd = CL_EXTERNAL_MEMORY_HANDLE_OPAQUE_FD_KHR,
7051*6fee86a4SJeremy Kemp     OpaqueWin32 = CL_EXTERNAL_MEMORY_HANDLE_OPAQUE_WIN32_KHR,
7052*6fee86a4SJeremy Kemp     OpaqueWin32Kmt = CL_EXTERNAL_MEMORY_HANDLE_OPAQUE_WIN32_KMT_KHR,
7053*6fee86a4SJeremy Kemp 
7054*6fee86a4SJeremy Kemp     D3D11Texture = CL_EXTERNAL_MEMORY_HANDLE_D3D11_TEXTURE_KHR,
7055*6fee86a4SJeremy Kemp     D3D11TextureKmt = CL_EXTERNAL_MEMORY_HANDLE_D3D11_TEXTURE_KMT_KHR,
7056*6fee86a4SJeremy Kemp 
7057*6fee86a4SJeremy Kemp     D3D12Heap = CL_EXTERNAL_MEMORY_HANDLE_D3D12_HEAP_KHR,
7058*6fee86a4SJeremy Kemp     D3D12Resource = CL_EXTERNAL_MEMORY_HANDLE_D3D12_RESOURCE_KHR,
7059*6fee86a4SJeremy Kemp 
7060*6fee86a4SJeremy Kemp     DmaBuf = CL_EXTERNAL_MEMORY_HANDLE_DMA_BUF_KHR,
7061*6fee86a4SJeremy Kemp };
7062*6fee86a4SJeremy Kemp #endif
7063*6fee86a4SJeremy Kemp 
7064*6fee86a4SJeremy Kemp enum class QueueProperties : cl_command_queue_properties
7065*6fee86a4SJeremy Kemp {
7066*6fee86a4SJeremy Kemp     None = 0,
7067*6fee86a4SJeremy Kemp     Profiling = CL_QUEUE_PROFILING_ENABLE,
7068*6fee86a4SJeremy Kemp     OutOfOrder = CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE,
7069*6fee86a4SJeremy Kemp };
7070*6fee86a4SJeremy Kemp 
operator |(QueueProperties lhs,QueueProperties rhs)7071*6fee86a4SJeremy Kemp inline QueueProperties operator|(QueueProperties lhs, QueueProperties rhs)
7072*6fee86a4SJeremy Kemp {
7073*6fee86a4SJeremy Kemp     return static_cast<QueueProperties>(static_cast<cl_command_queue_properties>(lhs) | static_cast<cl_command_queue_properties>(rhs));
7074*6fee86a4SJeremy Kemp }
7075*6fee86a4SJeremy Kemp 
operator &(QueueProperties lhs,QueueProperties rhs)7076*6fee86a4SJeremy Kemp inline QueueProperties operator&(QueueProperties lhs, QueueProperties rhs)
7077*6fee86a4SJeremy Kemp {
7078*6fee86a4SJeremy Kemp     return static_cast<QueueProperties>(static_cast<cl_command_queue_properties>(lhs) & static_cast<cl_command_queue_properties>(rhs));
7079*6fee86a4SJeremy Kemp }
7080*6fee86a4SJeremy Kemp 
7081*6fee86a4SJeremy Kemp /*! \class CommandQueue
7082*6fee86a4SJeremy Kemp  * \brief CommandQueue interface for cl_command_queue.
7083*6fee86a4SJeremy Kemp  */
7084*6fee86a4SJeremy Kemp class CommandQueue : public detail::Wrapper<cl_command_queue>
7085*6fee86a4SJeremy Kemp {
7086*6fee86a4SJeremy Kemp private:
7087*6fee86a4SJeremy Kemp     static std::once_flag default_initialized_;
7088*6fee86a4SJeremy Kemp     static CommandQueue default_;
7089*6fee86a4SJeremy Kemp     static cl_int default_error_;
7090*6fee86a4SJeremy Kemp 
7091*6fee86a4SJeremy Kemp     /*! \brief Create the default command queue returned by @ref getDefault.
7092*6fee86a4SJeremy Kemp      *
7093*6fee86a4SJeremy Kemp      * It sets default_error_ to indicate success or failure. It does not throw
7094*6fee86a4SJeremy Kemp      * @c cl::Error.
7095*6fee86a4SJeremy Kemp      */
makeDefault()7096*6fee86a4SJeremy Kemp     static void makeDefault()
7097*6fee86a4SJeremy Kemp     {
7098*6fee86a4SJeremy Kemp         /* We don't want to throw an error from this function, so we have to
7099*6fee86a4SJeremy Kemp          * catch and set the error flag.
7100*6fee86a4SJeremy Kemp          */
7101*6fee86a4SJeremy Kemp #if defined(CL_HPP_ENABLE_EXCEPTIONS)
7102*6fee86a4SJeremy Kemp         try
7103*6fee86a4SJeremy Kemp #endif
7104*6fee86a4SJeremy Kemp         {
7105*6fee86a4SJeremy Kemp             int error;
7106*6fee86a4SJeremy Kemp             Context context = Context::getDefault(&error);
7107*6fee86a4SJeremy Kemp 
7108*6fee86a4SJeremy Kemp             if (error != CL_SUCCESS) {
7109*6fee86a4SJeremy Kemp                 default_error_ = error;
7110*6fee86a4SJeremy Kemp             }
7111*6fee86a4SJeremy Kemp             else {
7112*6fee86a4SJeremy Kemp                 Device device = Device::getDefault();
7113*6fee86a4SJeremy Kemp                 default_ = CommandQueue(context, device, 0, &default_error_);
7114*6fee86a4SJeremy Kemp             }
7115*6fee86a4SJeremy Kemp         }
7116*6fee86a4SJeremy Kemp #if defined(CL_HPP_ENABLE_EXCEPTIONS)
7117*6fee86a4SJeremy Kemp         catch (cl::Error &e) {
7118*6fee86a4SJeremy Kemp             default_error_ = e.err();
7119*6fee86a4SJeremy Kemp         }
7120*6fee86a4SJeremy Kemp #endif
7121*6fee86a4SJeremy Kemp     }
7122*6fee86a4SJeremy Kemp 
7123*6fee86a4SJeremy Kemp     /*! \brief Create the default command queue.
7124*6fee86a4SJeremy Kemp      *
7125*6fee86a4SJeremy Kemp      * This sets @c default_. It does not throw
7126*6fee86a4SJeremy Kemp      * @c cl::Error.
7127*6fee86a4SJeremy Kemp      */
makeDefaultProvided(const CommandQueue & c)7128*6fee86a4SJeremy Kemp     static void makeDefaultProvided(const CommandQueue &c) {
7129*6fee86a4SJeremy Kemp         default_ = c;
7130*6fee86a4SJeremy Kemp     }
7131*6fee86a4SJeremy Kemp 
7132*6fee86a4SJeremy Kemp #ifdef cl_khr_external_memory
7133*6fee86a4SJeremy Kemp     static std::once_flag ext_memory_initialized_;
7134*6fee86a4SJeremy Kemp 
initMemoryExtension(const cl::Device & device)7135*6fee86a4SJeremy Kemp     static void initMemoryExtension(const cl::Device& device)
7136*6fee86a4SJeremy Kemp     {
7137*6fee86a4SJeremy Kemp         auto platform = device.getInfo<CL_DEVICE_PLATFORM>()();
7138*6fee86a4SJeremy Kemp 
7139*6fee86a4SJeremy Kemp         CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clEnqueueAcquireExternalMemObjectsKHR);
7140*6fee86a4SJeremy Kemp         CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clEnqueueReleaseExternalMemObjectsKHR);
7141*6fee86a4SJeremy Kemp 
7142*6fee86a4SJeremy Kemp         if ((pfn_clEnqueueAcquireExternalMemObjectsKHR == nullptr)
7143*6fee86a4SJeremy Kemp             && (pfn_clEnqueueReleaseExternalMemObjectsKHR == nullptr))
7144*6fee86a4SJeremy Kemp         {
7145*6fee86a4SJeremy Kemp             detail::errHandler(CL_INVALID_VALUE, __ENQUEUE_ACQUIRE_EXTERNAL_MEMORY_ERR);
7146*6fee86a4SJeremy Kemp         }
7147*6fee86a4SJeremy Kemp     }
7148*6fee86a4SJeremy Kemp #endif // cl_khr_external_memory
7149*6fee86a4SJeremy Kemp 
7150*6fee86a4SJeremy Kemp public:
7151*6fee86a4SJeremy Kemp #ifdef CL_HPP_UNIT_TEST_ENABLE
7152*6fee86a4SJeremy Kemp     /*! \brief Reset the default.
7153*6fee86a4SJeremy Kemp     *
7154*6fee86a4SJeremy Kemp     * This sets @c default_ to an empty value to support cleanup in
7155*6fee86a4SJeremy Kemp     * the unit test framework.
7156*6fee86a4SJeremy Kemp     * This function is not thread safe.
7157*6fee86a4SJeremy Kemp     */
unitTestClearDefault()7158*6fee86a4SJeremy Kemp     static void unitTestClearDefault() {
7159*6fee86a4SJeremy Kemp         default_ = CommandQueue();
7160*6fee86a4SJeremy Kemp     }
7161*6fee86a4SJeremy Kemp #endif // #ifdef CL_HPP_UNIT_TEST_ENABLE
7162*6fee86a4SJeremy Kemp 
7163*6fee86a4SJeremy Kemp 
7164*6fee86a4SJeremy Kemp     /*!
7165*6fee86a4SJeremy Kemp      * \brief Constructs a CommandQueue based on passed properties.
7166*6fee86a4SJeremy Kemp      * Will return an CL_INVALID_QUEUE_PROPERTIES error if CL_QUEUE_ON_DEVICE is specified.
7167*6fee86a4SJeremy Kemp      */
CommandQueue(cl_command_queue_properties properties,cl_int * err=nullptr)7168*6fee86a4SJeremy Kemp    CommandQueue(
7169*6fee86a4SJeremy Kemp         cl_command_queue_properties properties,
7170*6fee86a4SJeremy Kemp         cl_int* err = nullptr)
7171*6fee86a4SJeremy Kemp     {
7172*6fee86a4SJeremy Kemp         cl_int error;
7173*6fee86a4SJeremy Kemp 
7174*6fee86a4SJeremy Kemp         Context context = Context::getDefault(&error);
7175*6fee86a4SJeremy Kemp         detail::errHandler(error, __CREATE_CONTEXT_ERR);
7176*6fee86a4SJeremy Kemp 
7177*6fee86a4SJeremy Kemp         if (error != CL_SUCCESS) {
7178*6fee86a4SJeremy Kemp             if (err != nullptr) {
7179*6fee86a4SJeremy Kemp                 *err = error;
7180*6fee86a4SJeremy Kemp             }
7181*6fee86a4SJeremy Kemp         }
7182*6fee86a4SJeremy Kemp         else {
7183*6fee86a4SJeremy Kemp             Device device = context.getInfo<CL_CONTEXT_DEVICES>()[0];
7184*6fee86a4SJeremy Kemp             bool useWithProperties;
7185*6fee86a4SJeremy Kemp 
7186*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 200 && CL_HPP_MINIMUM_OPENCL_VERSION < 200
7187*6fee86a4SJeremy Kemp             // Run-time decision based on the actual platform
7188*6fee86a4SJeremy Kemp             {
7189*6fee86a4SJeremy Kemp                 cl_uint version = detail::getContextPlatformVersion(context());
7190*6fee86a4SJeremy Kemp                 useWithProperties = (version >= 0x20000); // OpenCL 2.0 or above
7191*6fee86a4SJeremy Kemp             }
7192*6fee86a4SJeremy Kemp #elif CL_HPP_TARGET_OPENCL_VERSION >= 200
7193*6fee86a4SJeremy Kemp             useWithProperties = true;
7194*6fee86a4SJeremy Kemp #else
7195*6fee86a4SJeremy Kemp             useWithProperties = false;
7196*6fee86a4SJeremy Kemp #endif
7197*6fee86a4SJeremy Kemp 
7198*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 200
7199*6fee86a4SJeremy Kemp             if (useWithProperties) {
7200*6fee86a4SJeremy Kemp                 cl_queue_properties queue_properties[] = {
7201*6fee86a4SJeremy Kemp                     CL_QUEUE_PROPERTIES, properties, 0 };
7202*6fee86a4SJeremy Kemp                 if ((properties & CL_QUEUE_ON_DEVICE) == 0) {
7203*6fee86a4SJeremy Kemp                     object_ = ::clCreateCommandQueueWithProperties(
7204*6fee86a4SJeremy Kemp                         context(), device(), queue_properties, &error);
7205*6fee86a4SJeremy Kemp                 }
7206*6fee86a4SJeremy Kemp                 else {
7207*6fee86a4SJeremy Kemp                     error = CL_INVALID_QUEUE_PROPERTIES;
7208*6fee86a4SJeremy Kemp                 }
7209*6fee86a4SJeremy Kemp 
7210*6fee86a4SJeremy Kemp                 detail::errHandler(error, __CREATE_COMMAND_QUEUE_WITH_PROPERTIES_ERR);
7211*6fee86a4SJeremy Kemp                 if (err != nullptr) {
7212*6fee86a4SJeremy Kemp                     *err = error;
7213*6fee86a4SJeremy Kemp                 }
7214*6fee86a4SJeremy Kemp             }
7215*6fee86a4SJeremy Kemp #endif // CL_HPP_TARGET_OPENCL_VERSION >= 200
7216*6fee86a4SJeremy Kemp #if CL_HPP_MINIMUM_OPENCL_VERSION < 200
7217*6fee86a4SJeremy Kemp             if (!useWithProperties) {
7218*6fee86a4SJeremy Kemp                 object_ = ::clCreateCommandQueue(
7219*6fee86a4SJeremy Kemp                     context(), device(), properties, &error);
7220*6fee86a4SJeremy Kemp 
7221*6fee86a4SJeremy Kemp                 detail::errHandler(error, __CREATE_COMMAND_QUEUE_ERR);
7222*6fee86a4SJeremy Kemp                 if (err != nullptr) {
7223*6fee86a4SJeremy Kemp                     *err = error;
7224*6fee86a4SJeremy Kemp                 }
7225*6fee86a4SJeremy Kemp             }
7226*6fee86a4SJeremy Kemp #endif // CL_HPP_MINIMUM_OPENCL_VERSION < 200
7227*6fee86a4SJeremy Kemp         }
7228*6fee86a4SJeremy Kemp     }
7229*6fee86a4SJeremy Kemp 
7230*6fee86a4SJeremy Kemp    /*!
7231*6fee86a4SJeremy Kemp     * \brief Constructs a CommandQueue based on passed properties.
7232*6fee86a4SJeremy Kemp     * Will return an CL_INVALID_QUEUE_PROPERTIES error if CL_QUEUE_ON_DEVICE is specified.
7233*6fee86a4SJeremy Kemp     */
CommandQueue(QueueProperties properties,cl_int * err=nullptr)7234*6fee86a4SJeremy Kemp    CommandQueue(
7235*6fee86a4SJeremy Kemp        QueueProperties properties,
7236*6fee86a4SJeremy Kemp        cl_int* err = nullptr)
7237*6fee86a4SJeremy Kemp    {
7238*6fee86a4SJeremy Kemp        cl_int error;
7239*6fee86a4SJeremy Kemp 
7240*6fee86a4SJeremy Kemp        Context context = Context::getDefault(&error);
7241*6fee86a4SJeremy Kemp        detail::errHandler(error, __CREATE_CONTEXT_ERR);
7242*6fee86a4SJeremy Kemp 
7243*6fee86a4SJeremy Kemp        if (error != CL_SUCCESS) {
7244*6fee86a4SJeremy Kemp            if (err != nullptr) {
7245*6fee86a4SJeremy Kemp                *err = error;
7246*6fee86a4SJeremy Kemp            }
7247*6fee86a4SJeremy Kemp        }
7248*6fee86a4SJeremy Kemp        else {
7249*6fee86a4SJeremy Kemp            Device device = context.getInfo<CL_CONTEXT_DEVICES>()[0];
7250*6fee86a4SJeremy Kemp            bool useWithProperties;
7251*6fee86a4SJeremy Kemp 
7252*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 200 && CL_HPP_MINIMUM_OPENCL_VERSION < 200
7253*6fee86a4SJeremy Kemp            // Run-time decision based on the actual platform
7254*6fee86a4SJeremy Kemp            {
7255*6fee86a4SJeremy Kemp                cl_uint version = detail::getContextPlatformVersion(context());
7256*6fee86a4SJeremy Kemp                useWithProperties = (version >= 0x20000); // OpenCL 2.0 or above
7257*6fee86a4SJeremy Kemp            }
7258*6fee86a4SJeremy Kemp #elif CL_HPP_TARGET_OPENCL_VERSION >= 200
7259*6fee86a4SJeremy Kemp            useWithProperties = true;
7260*6fee86a4SJeremy Kemp #else
7261*6fee86a4SJeremy Kemp            useWithProperties = false;
7262*6fee86a4SJeremy Kemp #endif
7263*6fee86a4SJeremy Kemp 
7264*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 200
7265*6fee86a4SJeremy Kemp            if (useWithProperties) {
7266*6fee86a4SJeremy Kemp                cl_queue_properties queue_properties[] = {
7267*6fee86a4SJeremy Kemp                    CL_QUEUE_PROPERTIES, static_cast<cl_queue_properties>(properties), 0 };
7268*6fee86a4SJeremy Kemp 
7269*6fee86a4SJeremy Kemp                object_ = ::clCreateCommandQueueWithProperties(
7270*6fee86a4SJeremy Kemp                    context(), device(), queue_properties, &error);
7271*6fee86a4SJeremy Kemp 
7272*6fee86a4SJeremy Kemp                detail::errHandler(error, __CREATE_COMMAND_QUEUE_WITH_PROPERTIES_ERR);
7273*6fee86a4SJeremy Kemp                if (err != nullptr) {
7274*6fee86a4SJeremy Kemp                    *err = error;
7275*6fee86a4SJeremy Kemp                }
7276*6fee86a4SJeremy Kemp            }
7277*6fee86a4SJeremy Kemp #endif // CL_HPP_TARGET_OPENCL_VERSION >= 200
7278*6fee86a4SJeremy Kemp #if CL_HPP_MINIMUM_OPENCL_VERSION < 200
7279*6fee86a4SJeremy Kemp            if (!useWithProperties) {
7280*6fee86a4SJeremy Kemp                object_ = ::clCreateCommandQueue(
7281*6fee86a4SJeremy Kemp                    context(), device(), static_cast<cl_command_queue_properties>(properties), &error);
7282*6fee86a4SJeremy Kemp 
7283*6fee86a4SJeremy Kemp                detail::errHandler(error, __CREATE_COMMAND_QUEUE_ERR);
7284*6fee86a4SJeremy Kemp                if (err != nullptr) {
7285*6fee86a4SJeremy Kemp                    *err = error;
7286*6fee86a4SJeremy Kemp                }
7287*6fee86a4SJeremy Kemp            }
7288*6fee86a4SJeremy Kemp #endif // CL_HPP_MINIMUM_OPENCL_VERSION < 200
7289*6fee86a4SJeremy Kemp 
7290*6fee86a4SJeremy Kemp        }
7291*6fee86a4SJeremy Kemp    }
7292*6fee86a4SJeremy Kemp 
7293*6fee86a4SJeremy Kemp     /*!
7294*6fee86a4SJeremy Kemp      * \brief Constructs a CommandQueue for an implementation defined device in the given context
7295*6fee86a4SJeremy Kemp      * Will return an CL_INVALID_QUEUE_PROPERTIES error if CL_QUEUE_ON_DEVICE is specified.
7296*6fee86a4SJeremy Kemp      */
CommandQueue(const Context & context,cl_command_queue_properties properties=0,cl_int * err=nullptr)7297*6fee86a4SJeremy Kemp     explicit CommandQueue(
7298*6fee86a4SJeremy Kemp         const Context& context,
7299*6fee86a4SJeremy Kemp         cl_command_queue_properties properties = 0,
7300*6fee86a4SJeremy Kemp         cl_int* err = nullptr)
7301*6fee86a4SJeremy Kemp     {
7302*6fee86a4SJeremy Kemp         cl_int error;
7303*6fee86a4SJeremy Kemp         bool useWithProperties;
7304*6fee86a4SJeremy Kemp         vector<cl::Device> devices;
7305*6fee86a4SJeremy Kemp         error = context.getInfo(CL_CONTEXT_DEVICES, &devices);
7306*6fee86a4SJeremy Kemp 
7307*6fee86a4SJeremy Kemp         detail::errHandler(error, __CREATE_CONTEXT_ERR);
7308*6fee86a4SJeremy Kemp 
7309*6fee86a4SJeremy Kemp         if (error != CL_SUCCESS)
7310*6fee86a4SJeremy Kemp         {
7311*6fee86a4SJeremy Kemp             if (err != nullptr) {
7312*6fee86a4SJeremy Kemp                 *err = error;
7313*6fee86a4SJeremy Kemp             }
7314*6fee86a4SJeremy Kemp             return;
7315*6fee86a4SJeremy Kemp         }
7316*6fee86a4SJeremy Kemp 
7317*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 200 && CL_HPP_MINIMUM_OPENCL_VERSION < 200
7318*6fee86a4SJeremy Kemp         // Run-time decision based on the actual platform
7319*6fee86a4SJeremy Kemp         {
7320*6fee86a4SJeremy Kemp             cl_uint version = detail::getContextPlatformVersion(context());
7321*6fee86a4SJeremy Kemp             useWithProperties = (version >= 0x20000); // OpenCL 2.0 or above
7322*6fee86a4SJeremy Kemp         }
7323*6fee86a4SJeremy Kemp #elif CL_HPP_TARGET_OPENCL_VERSION >= 200
7324*6fee86a4SJeremy Kemp         useWithProperties = true;
7325*6fee86a4SJeremy Kemp #else
7326*6fee86a4SJeremy Kemp         useWithProperties = false;
7327*6fee86a4SJeremy Kemp #endif
7328*6fee86a4SJeremy Kemp 
7329*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 200
7330*6fee86a4SJeremy Kemp         if (useWithProperties) {
7331*6fee86a4SJeremy Kemp             cl_queue_properties queue_properties[] = {
7332*6fee86a4SJeremy Kemp                 CL_QUEUE_PROPERTIES, properties, 0 };
7333*6fee86a4SJeremy Kemp             if ((properties & CL_QUEUE_ON_DEVICE) == 0) {
7334*6fee86a4SJeremy Kemp                 object_ = ::clCreateCommandQueueWithProperties(
7335*6fee86a4SJeremy Kemp                     context(), devices[0](), queue_properties, &error);
7336*6fee86a4SJeremy Kemp             }
7337*6fee86a4SJeremy Kemp             else {
7338*6fee86a4SJeremy Kemp                 error = CL_INVALID_QUEUE_PROPERTIES;
7339*6fee86a4SJeremy Kemp             }
7340*6fee86a4SJeremy Kemp 
7341*6fee86a4SJeremy Kemp             detail::errHandler(error, __CREATE_COMMAND_QUEUE_WITH_PROPERTIES_ERR);
7342*6fee86a4SJeremy Kemp             if (err != nullptr) {
7343*6fee86a4SJeremy Kemp                 *err = error;
7344*6fee86a4SJeremy Kemp             }
7345*6fee86a4SJeremy Kemp         }
7346*6fee86a4SJeremy Kemp #endif // CL_HPP_TARGET_OPENCL_VERSION >= 200
7347*6fee86a4SJeremy Kemp #if CL_HPP_MINIMUM_OPENCL_VERSION < 200
7348*6fee86a4SJeremy Kemp         if (!useWithProperties) {
7349*6fee86a4SJeremy Kemp             object_ = ::clCreateCommandQueue(
7350*6fee86a4SJeremy Kemp                 context(), devices[0](), properties, &error);
7351*6fee86a4SJeremy Kemp 
7352*6fee86a4SJeremy Kemp             detail::errHandler(error, __CREATE_COMMAND_QUEUE_ERR);
7353*6fee86a4SJeremy Kemp             if (err != nullptr) {
7354*6fee86a4SJeremy Kemp                 *err = error;
7355*6fee86a4SJeremy Kemp             }
7356*6fee86a4SJeremy Kemp         }
7357*6fee86a4SJeremy Kemp #endif // CL_HPP_MINIMUM_OPENCL_VERSION < 200
7358*6fee86a4SJeremy Kemp     }
7359*6fee86a4SJeremy Kemp 
7360*6fee86a4SJeremy Kemp     /*!
7361*6fee86a4SJeremy Kemp     * \brief Constructs a CommandQueue for an implementation defined device in the given context
7362*6fee86a4SJeremy Kemp     * Will return an CL_INVALID_QUEUE_PROPERTIES error if CL_QUEUE_ON_DEVICE is specified.
7363*6fee86a4SJeremy Kemp     */
CommandQueue(const Context & context,QueueProperties properties,cl_int * err=nullptr)7364*6fee86a4SJeremy Kemp     explicit CommandQueue(
7365*6fee86a4SJeremy Kemp         const Context& context,
7366*6fee86a4SJeremy Kemp         QueueProperties properties,
7367*6fee86a4SJeremy Kemp         cl_int* err = nullptr)
7368*6fee86a4SJeremy Kemp     {
7369*6fee86a4SJeremy Kemp         cl_int error;
7370*6fee86a4SJeremy Kemp         bool useWithProperties;
7371*6fee86a4SJeremy Kemp         vector<cl::Device> devices;
7372*6fee86a4SJeremy Kemp         error = context.getInfo(CL_CONTEXT_DEVICES, &devices);
7373*6fee86a4SJeremy Kemp 
7374*6fee86a4SJeremy Kemp         detail::errHandler(error, __CREATE_CONTEXT_ERR);
7375*6fee86a4SJeremy Kemp 
7376*6fee86a4SJeremy Kemp         if (error != CL_SUCCESS)
7377*6fee86a4SJeremy Kemp         {
7378*6fee86a4SJeremy Kemp             if (err != nullptr) {
7379*6fee86a4SJeremy Kemp                 *err = error;
7380*6fee86a4SJeremy Kemp             }
7381*6fee86a4SJeremy Kemp             return;
7382*6fee86a4SJeremy Kemp         }
7383*6fee86a4SJeremy Kemp 
7384*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 200 && CL_HPP_MINIMUM_OPENCL_VERSION < 200
7385*6fee86a4SJeremy Kemp         // Run-time decision based on the actual platform
7386*6fee86a4SJeremy Kemp         {
7387*6fee86a4SJeremy Kemp             cl_uint version = detail::getContextPlatformVersion(context());
7388*6fee86a4SJeremy Kemp             useWithProperties = (version >= 0x20000); // OpenCL 2.0 or above
7389*6fee86a4SJeremy Kemp         }
7390*6fee86a4SJeremy Kemp #elif CL_HPP_TARGET_OPENCL_VERSION >= 200
7391*6fee86a4SJeremy Kemp         useWithProperties = true;
7392*6fee86a4SJeremy Kemp #else
7393*6fee86a4SJeremy Kemp         useWithProperties = false;
7394*6fee86a4SJeremy Kemp #endif
7395*6fee86a4SJeremy Kemp 
7396*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 200
7397*6fee86a4SJeremy Kemp         if (useWithProperties) {
7398*6fee86a4SJeremy Kemp             cl_queue_properties queue_properties[] = {
7399*6fee86a4SJeremy Kemp                 CL_QUEUE_PROPERTIES, static_cast<cl_queue_properties>(properties), 0 };
7400*6fee86a4SJeremy Kemp             object_ = ::clCreateCommandQueueWithProperties(
7401*6fee86a4SJeremy Kemp                 context(), devices[0](), queue_properties, &error);
7402*6fee86a4SJeremy Kemp 
7403*6fee86a4SJeremy Kemp             detail::errHandler(error, __CREATE_COMMAND_QUEUE_WITH_PROPERTIES_ERR);
7404*6fee86a4SJeremy Kemp             if (err != nullptr) {
7405*6fee86a4SJeremy Kemp                 *err = error;
7406*6fee86a4SJeremy Kemp             }
7407*6fee86a4SJeremy Kemp         }
7408*6fee86a4SJeremy Kemp #endif // CL_HPP_TARGET_OPENCL_VERSION >= 200
7409*6fee86a4SJeremy Kemp #if CL_HPP_MINIMUM_OPENCL_VERSION < 200
7410*6fee86a4SJeremy Kemp         if (!useWithProperties) {
7411*6fee86a4SJeremy Kemp             object_ = ::clCreateCommandQueue(
7412*6fee86a4SJeremy Kemp                 context(), devices[0](), static_cast<cl_command_queue_properties>(properties), &error);
7413*6fee86a4SJeremy Kemp 
7414*6fee86a4SJeremy Kemp             detail::errHandler(error, __CREATE_COMMAND_QUEUE_ERR);
7415*6fee86a4SJeremy Kemp             if (err != nullptr) {
7416*6fee86a4SJeremy Kemp                 *err = error;
7417*6fee86a4SJeremy Kemp             }
7418*6fee86a4SJeremy Kemp         }
7419*6fee86a4SJeremy Kemp #endif // CL_HPP_MINIMUM_OPENCL_VERSION < 200
7420*6fee86a4SJeremy Kemp     }
7421*6fee86a4SJeremy Kemp 
7422*6fee86a4SJeremy Kemp     /*!
7423*6fee86a4SJeremy Kemp      * \brief Constructs a CommandQueue for a passed device and context
7424*6fee86a4SJeremy Kemp      * Will return an CL_INVALID_QUEUE_PROPERTIES error if CL_QUEUE_ON_DEVICE is specified.
7425*6fee86a4SJeremy Kemp      */
CommandQueue(const Context & context,const Device & device,cl_command_queue_properties properties=0,cl_int * err=nullptr)7426*6fee86a4SJeremy Kemp     CommandQueue(
7427*6fee86a4SJeremy Kemp         const Context& context,
7428*6fee86a4SJeremy Kemp         const Device& device,
7429*6fee86a4SJeremy Kemp         cl_command_queue_properties properties = 0,
7430*6fee86a4SJeremy Kemp         cl_int* err = nullptr)
7431*6fee86a4SJeremy Kemp     {
7432*6fee86a4SJeremy Kemp         cl_int error;
7433*6fee86a4SJeremy Kemp         bool useWithProperties;
7434*6fee86a4SJeremy Kemp 
7435*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 200 && CL_HPP_MINIMUM_OPENCL_VERSION < 200
7436*6fee86a4SJeremy Kemp         // Run-time decision based on the actual platform
7437*6fee86a4SJeremy Kemp         {
7438*6fee86a4SJeremy Kemp             cl_uint version = detail::getContextPlatformVersion(context());
7439*6fee86a4SJeremy Kemp             useWithProperties = (version >= 0x20000); // OpenCL 2.0 or above
7440*6fee86a4SJeremy Kemp         }
7441*6fee86a4SJeremy Kemp #elif CL_HPP_TARGET_OPENCL_VERSION >= 200
7442*6fee86a4SJeremy Kemp         useWithProperties = true;
7443*6fee86a4SJeremy Kemp #else
7444*6fee86a4SJeremy Kemp         useWithProperties = false;
7445*6fee86a4SJeremy Kemp #endif
7446*6fee86a4SJeremy Kemp 
7447*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 200
7448*6fee86a4SJeremy Kemp         if (useWithProperties) {
7449*6fee86a4SJeremy Kemp             cl_queue_properties queue_properties[] = {
7450*6fee86a4SJeremy Kemp                 CL_QUEUE_PROPERTIES, properties, 0 };
7451*6fee86a4SJeremy Kemp             object_ = ::clCreateCommandQueueWithProperties(
7452*6fee86a4SJeremy Kemp                 context(), device(), queue_properties, &error);
7453*6fee86a4SJeremy Kemp 
7454*6fee86a4SJeremy Kemp             detail::errHandler(error, __CREATE_COMMAND_QUEUE_WITH_PROPERTIES_ERR);
7455*6fee86a4SJeremy Kemp             if (err != nullptr) {
7456*6fee86a4SJeremy Kemp                 *err = error;
7457*6fee86a4SJeremy Kemp             }
7458*6fee86a4SJeremy Kemp         }
7459*6fee86a4SJeremy Kemp #endif // CL_HPP_TARGET_OPENCL_VERSION >= 200
7460*6fee86a4SJeremy Kemp #if CL_HPP_MINIMUM_OPENCL_VERSION < 200
7461*6fee86a4SJeremy Kemp         if (!useWithProperties) {
7462*6fee86a4SJeremy Kemp             object_ = ::clCreateCommandQueue(
7463*6fee86a4SJeremy Kemp                 context(), device(), properties, &error);
7464*6fee86a4SJeremy Kemp 
7465*6fee86a4SJeremy Kemp             detail::errHandler(error, __CREATE_COMMAND_QUEUE_ERR);
7466*6fee86a4SJeremy Kemp             if (err != nullptr) {
7467*6fee86a4SJeremy Kemp                 *err = error;
7468*6fee86a4SJeremy Kemp             }
7469*6fee86a4SJeremy Kemp         }
7470*6fee86a4SJeremy Kemp #endif // CL_HPP_MINIMUM_OPENCL_VERSION < 200
7471*6fee86a4SJeremy Kemp     }
7472*6fee86a4SJeremy Kemp 
7473*6fee86a4SJeremy Kemp     /*!
7474*6fee86a4SJeremy Kemp      * \brief Constructs a CommandQueue for a passed device and context
7475*6fee86a4SJeremy Kemp      * Will return an CL_INVALID_QUEUE_PROPERTIES error if CL_QUEUE_ON_DEVICE is specified.
7476*6fee86a4SJeremy Kemp      */
CommandQueue(const Context & context,const Device & device,QueueProperties properties,cl_int * err=nullptr)7477*6fee86a4SJeremy Kemp     CommandQueue(
7478*6fee86a4SJeremy Kemp         const Context& context,
7479*6fee86a4SJeremy Kemp         const Device& device,
7480*6fee86a4SJeremy Kemp         QueueProperties properties,
7481*6fee86a4SJeremy Kemp         cl_int* err = nullptr)
7482*6fee86a4SJeremy Kemp     {
7483*6fee86a4SJeremy Kemp         cl_int error;
7484*6fee86a4SJeremy Kemp         bool useWithProperties;
7485*6fee86a4SJeremy Kemp 
7486*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 200 && CL_HPP_MINIMUM_OPENCL_VERSION < 200
7487*6fee86a4SJeremy Kemp         // Run-time decision based on the actual platform
7488*6fee86a4SJeremy Kemp         {
7489*6fee86a4SJeremy Kemp             cl_uint version = detail::getContextPlatformVersion(context());
7490*6fee86a4SJeremy Kemp             useWithProperties = (version >= 0x20000); // OpenCL 2.0 or above
7491*6fee86a4SJeremy Kemp         }
7492*6fee86a4SJeremy Kemp #elif CL_HPP_TARGET_OPENCL_VERSION >= 200
7493*6fee86a4SJeremy Kemp         useWithProperties = true;
7494*6fee86a4SJeremy Kemp #else
7495*6fee86a4SJeremy Kemp         useWithProperties = false;
7496*6fee86a4SJeremy Kemp #endif
7497*6fee86a4SJeremy Kemp 
7498*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 200
7499*6fee86a4SJeremy Kemp         if (useWithProperties) {
7500*6fee86a4SJeremy Kemp             cl_queue_properties queue_properties[] = {
7501*6fee86a4SJeremy Kemp                 CL_QUEUE_PROPERTIES, static_cast<cl_queue_properties>(properties), 0 };
7502*6fee86a4SJeremy Kemp             object_ = ::clCreateCommandQueueWithProperties(
7503*6fee86a4SJeremy Kemp                 context(), device(), queue_properties, &error);
7504*6fee86a4SJeremy Kemp 
7505*6fee86a4SJeremy Kemp             detail::errHandler(error, __CREATE_COMMAND_QUEUE_WITH_PROPERTIES_ERR);
7506*6fee86a4SJeremy Kemp             if (err != nullptr) {
7507*6fee86a4SJeremy Kemp                 *err = error;
7508*6fee86a4SJeremy Kemp             }
7509*6fee86a4SJeremy Kemp         }
7510*6fee86a4SJeremy Kemp #endif // CL_HPP_TARGET_OPENCL_VERSION >= 200
7511*6fee86a4SJeremy Kemp #if CL_HPP_MINIMUM_OPENCL_VERSION < 200
7512*6fee86a4SJeremy Kemp         if (!useWithProperties) {
7513*6fee86a4SJeremy Kemp             object_ = ::clCreateCommandQueue(
7514*6fee86a4SJeremy Kemp                 context(), device(), static_cast<cl_command_queue_properties>(properties), &error);
7515*6fee86a4SJeremy Kemp 
7516*6fee86a4SJeremy Kemp             detail::errHandler(error, __CREATE_COMMAND_QUEUE_ERR);
7517*6fee86a4SJeremy Kemp             if (err != nullptr) {
7518*6fee86a4SJeremy Kemp                 *err = error;
7519*6fee86a4SJeremy Kemp             }
7520*6fee86a4SJeremy Kemp         }
7521*6fee86a4SJeremy Kemp #endif // CL_HPP_MINIMUM_OPENCL_VERSION < 200
7522*6fee86a4SJeremy Kemp     }
7523*6fee86a4SJeremy Kemp 
getDefault(cl_int * err=nullptr)7524*6fee86a4SJeremy Kemp     static CommandQueue getDefault(cl_int * err = nullptr)
7525*6fee86a4SJeremy Kemp     {
7526*6fee86a4SJeremy Kemp         std::call_once(default_initialized_, makeDefault);
7527*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 200
7528*6fee86a4SJeremy Kemp         detail::errHandler(default_error_, __CREATE_COMMAND_QUEUE_WITH_PROPERTIES_ERR);
7529*6fee86a4SJeremy Kemp #else // CL_HPP_TARGET_OPENCL_VERSION >= 200
7530*6fee86a4SJeremy Kemp         detail::errHandler(default_error_, __CREATE_COMMAND_QUEUE_ERR);
7531*6fee86a4SJeremy Kemp #endif // CL_HPP_TARGET_OPENCL_VERSION >= 200
7532*6fee86a4SJeremy Kemp         if (err != nullptr) {
7533*6fee86a4SJeremy Kemp             *err = default_error_;
7534*6fee86a4SJeremy Kemp         }
7535*6fee86a4SJeremy Kemp         return default_;
7536*6fee86a4SJeremy Kemp     }
7537*6fee86a4SJeremy Kemp 
7538*6fee86a4SJeremy Kemp     /**
7539*6fee86a4SJeremy Kemp      * Modify the default command queue to be used by
7540*6fee86a4SJeremy Kemp      * subsequent operations.
7541*6fee86a4SJeremy Kemp      * Will only set the default if no default was previously created.
7542*6fee86a4SJeremy Kemp      * @return updated default command queue.
7543*6fee86a4SJeremy Kemp      *         Should be compared to the passed value to ensure that it was updated.
7544*6fee86a4SJeremy Kemp      */
setDefault(const CommandQueue & default_queue)7545*6fee86a4SJeremy Kemp     static CommandQueue setDefault(const CommandQueue &default_queue)
7546*6fee86a4SJeremy Kemp     {
7547*6fee86a4SJeremy Kemp         std::call_once(default_initialized_, makeDefaultProvided, std::cref(default_queue));
7548*6fee86a4SJeremy Kemp         detail::errHandler(default_error_);
7549*6fee86a4SJeremy Kemp         return default_;
7550*6fee86a4SJeremy Kemp     }
7551*6fee86a4SJeremy Kemp 
CommandQueue()7552*6fee86a4SJeremy Kemp     CommandQueue() { }
7553*6fee86a4SJeremy Kemp 
7554*6fee86a4SJeremy Kemp 
7555*6fee86a4SJeremy Kemp     /*! \brief Constructor from cl_command_queue - takes ownership.
7556*6fee86a4SJeremy Kemp      *
7557*6fee86a4SJeremy Kemp      * \param retainObject will cause the constructor to retain its cl object.
7558*6fee86a4SJeremy Kemp      *                     Defaults to false to maintain compatibility with
7559*6fee86a4SJeremy Kemp      *                     earlier versions.
7560*6fee86a4SJeremy Kemp      */
CommandQueue(const cl_command_queue & commandQueue,bool retainObject=false)7561*6fee86a4SJeremy Kemp     explicit CommandQueue(const cl_command_queue& commandQueue, bool retainObject = false) :
7562*6fee86a4SJeremy Kemp         detail::Wrapper<cl_type>(commandQueue, retainObject) { }
7563*6fee86a4SJeremy Kemp 
operator =(const cl_command_queue & rhs)7564*6fee86a4SJeremy Kemp     CommandQueue& operator = (const cl_command_queue& rhs)
7565*6fee86a4SJeremy Kemp     {
7566*6fee86a4SJeremy Kemp         detail::Wrapper<cl_type>::operator=(rhs);
7567*6fee86a4SJeremy Kemp         return *this;
7568*6fee86a4SJeremy Kemp     }
7569*6fee86a4SJeremy Kemp 
7570*6fee86a4SJeremy Kemp     template <typename T>
getInfo(cl_command_queue_info name,T * param) const7571*6fee86a4SJeremy Kemp     cl_int getInfo(cl_command_queue_info name, T* param) const
7572*6fee86a4SJeremy Kemp     {
7573*6fee86a4SJeremy Kemp         return detail::errHandler(
7574*6fee86a4SJeremy Kemp             detail::getInfo(
7575*6fee86a4SJeremy Kemp                 &::clGetCommandQueueInfo, object_, name, param),
7576*6fee86a4SJeremy Kemp                 __GET_COMMAND_QUEUE_INFO_ERR);
7577*6fee86a4SJeremy Kemp     }
7578*6fee86a4SJeremy Kemp 
7579*6fee86a4SJeremy Kemp     template <cl_command_queue_info name> typename
7580*6fee86a4SJeremy Kemp     detail::param_traits<detail::cl_command_queue_info, name>::param_type
getInfo(cl_int * err=nullptr) const7581*6fee86a4SJeremy Kemp     getInfo(cl_int* err = nullptr) const
7582*6fee86a4SJeremy Kemp     {
7583*6fee86a4SJeremy Kemp         typename detail::param_traits<
7584*6fee86a4SJeremy Kemp             detail::cl_command_queue_info, name>::param_type param;
7585*6fee86a4SJeremy Kemp         cl_int result = getInfo(name, &param);
7586*6fee86a4SJeremy Kemp         if (err != nullptr) {
7587*6fee86a4SJeremy Kemp             *err = result;
7588*6fee86a4SJeremy Kemp         }
7589*6fee86a4SJeremy Kemp         return param;
7590*6fee86a4SJeremy Kemp     }
7591*6fee86a4SJeremy Kemp 
enqueueReadBuffer(const Buffer & buffer,cl_bool blocking,size_type offset,size_type size,void * ptr,const vector<Event> * events=nullptr,Event * event=nullptr) const7592*6fee86a4SJeremy Kemp     cl_int enqueueReadBuffer(
7593*6fee86a4SJeremy Kemp         const Buffer& buffer,
7594*6fee86a4SJeremy Kemp         cl_bool blocking,
7595*6fee86a4SJeremy Kemp         size_type offset,
7596*6fee86a4SJeremy Kemp         size_type size,
7597*6fee86a4SJeremy Kemp         void* ptr,
7598*6fee86a4SJeremy Kemp         const vector<Event>* events = nullptr,
7599*6fee86a4SJeremy Kemp         Event* event = nullptr) const
7600*6fee86a4SJeremy Kemp     {
7601*6fee86a4SJeremy Kemp         cl_event tmp;
7602*6fee86a4SJeremy Kemp         cl_int err = detail::errHandler(
7603*6fee86a4SJeremy Kemp             ::clEnqueueReadBuffer(
7604*6fee86a4SJeremy Kemp                 object_, buffer(), blocking, offset, size,
7605*6fee86a4SJeremy Kemp                 ptr,
7606*6fee86a4SJeremy Kemp                 (events != nullptr) ? (cl_uint) events->size() : 0,
7607*6fee86a4SJeremy Kemp                 (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
7608*6fee86a4SJeremy Kemp                 (event != nullptr) ? &tmp : nullptr),
7609*6fee86a4SJeremy Kemp             __ENQUEUE_READ_BUFFER_ERR);
7610*6fee86a4SJeremy Kemp 
7611*6fee86a4SJeremy Kemp         if (event != nullptr && err == CL_SUCCESS)
7612*6fee86a4SJeremy Kemp             *event = tmp;
7613*6fee86a4SJeremy Kemp 
7614*6fee86a4SJeremy Kemp         return err;
7615*6fee86a4SJeremy Kemp     }
7616*6fee86a4SJeremy Kemp 
enqueueWriteBuffer(const Buffer & buffer,cl_bool blocking,size_type offset,size_type size,const void * ptr,const vector<Event> * events=nullptr,Event * event=nullptr) const7617*6fee86a4SJeremy Kemp     cl_int enqueueWriteBuffer(
7618*6fee86a4SJeremy Kemp         const Buffer& buffer,
7619*6fee86a4SJeremy Kemp         cl_bool blocking,
7620*6fee86a4SJeremy Kemp         size_type offset,
7621*6fee86a4SJeremy Kemp         size_type size,
7622*6fee86a4SJeremy Kemp         const void* ptr,
7623*6fee86a4SJeremy Kemp         const vector<Event>* events = nullptr,
7624*6fee86a4SJeremy Kemp         Event* event = nullptr) const
7625*6fee86a4SJeremy Kemp     {
7626*6fee86a4SJeremy Kemp         cl_event tmp;
7627*6fee86a4SJeremy Kemp         cl_int err = detail::errHandler(
7628*6fee86a4SJeremy Kemp             ::clEnqueueWriteBuffer(
7629*6fee86a4SJeremy Kemp                 object_, buffer(), blocking, offset, size,
7630*6fee86a4SJeremy Kemp                 ptr,
7631*6fee86a4SJeremy Kemp                 (events != nullptr) ? (cl_uint) events->size() : 0,
7632*6fee86a4SJeremy Kemp                 (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
7633*6fee86a4SJeremy Kemp                 (event != nullptr) ? &tmp : nullptr),
7634*6fee86a4SJeremy Kemp                 __ENQUEUE_WRITE_BUFFER_ERR);
7635*6fee86a4SJeremy Kemp 
7636*6fee86a4SJeremy Kemp         if (event != nullptr && err == CL_SUCCESS)
7637*6fee86a4SJeremy Kemp             *event = tmp;
7638*6fee86a4SJeremy Kemp 
7639*6fee86a4SJeremy Kemp         return err;
7640*6fee86a4SJeremy Kemp     }
7641*6fee86a4SJeremy Kemp 
enqueueCopyBuffer(const Buffer & src,const Buffer & dst,size_type src_offset,size_type dst_offset,size_type size,const vector<Event> * events=nullptr,Event * event=nullptr) const7642*6fee86a4SJeremy Kemp     cl_int enqueueCopyBuffer(
7643*6fee86a4SJeremy Kemp         const Buffer& src,
7644*6fee86a4SJeremy Kemp         const Buffer& dst,
7645*6fee86a4SJeremy Kemp         size_type src_offset,
7646*6fee86a4SJeremy Kemp         size_type dst_offset,
7647*6fee86a4SJeremy Kemp         size_type size,
7648*6fee86a4SJeremy Kemp         const vector<Event>* events = nullptr,
7649*6fee86a4SJeremy Kemp         Event* event = nullptr) const
7650*6fee86a4SJeremy Kemp     {
7651*6fee86a4SJeremy Kemp         cl_event tmp;
7652*6fee86a4SJeremy Kemp         cl_int err = detail::errHandler(
7653*6fee86a4SJeremy Kemp             ::clEnqueueCopyBuffer(
7654*6fee86a4SJeremy Kemp                 object_, src(), dst(), src_offset, dst_offset, size,
7655*6fee86a4SJeremy Kemp                 (events != nullptr) ? (cl_uint) events->size() : 0,
7656*6fee86a4SJeremy Kemp                 (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
7657*6fee86a4SJeremy Kemp                 (event != nullptr) ? &tmp : nullptr),
7658*6fee86a4SJeremy Kemp             __ENQEUE_COPY_BUFFER_ERR);
7659*6fee86a4SJeremy Kemp 
7660*6fee86a4SJeremy Kemp         if (event != nullptr && err == CL_SUCCESS)
7661*6fee86a4SJeremy Kemp             *event = tmp;
7662*6fee86a4SJeremy Kemp 
7663*6fee86a4SJeremy Kemp         return err;
7664*6fee86a4SJeremy Kemp     }
7665*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 110
enqueueReadBufferRect(const Buffer & buffer,cl_bool blocking,const array<size_type,3> & buffer_offset,const array<size_type,3> & host_offset,const array<size_type,3> & region,size_type buffer_row_pitch,size_type buffer_slice_pitch,size_type host_row_pitch,size_type host_slice_pitch,void * ptr,const vector<Event> * events=nullptr,Event * event=nullptr) const7666*6fee86a4SJeremy Kemp     cl_int enqueueReadBufferRect(
7667*6fee86a4SJeremy Kemp         const Buffer& buffer,
7668*6fee86a4SJeremy Kemp         cl_bool blocking,
7669*6fee86a4SJeremy Kemp         const array<size_type, 3>& buffer_offset,
7670*6fee86a4SJeremy Kemp         const array<size_type, 3>& host_offset,
7671*6fee86a4SJeremy Kemp         const array<size_type, 3>& region,
7672*6fee86a4SJeremy Kemp         size_type buffer_row_pitch,
7673*6fee86a4SJeremy Kemp         size_type buffer_slice_pitch,
7674*6fee86a4SJeremy Kemp         size_type host_row_pitch,
7675*6fee86a4SJeremy Kemp         size_type host_slice_pitch,
7676*6fee86a4SJeremy Kemp         void *ptr,
7677*6fee86a4SJeremy Kemp         const vector<Event>* events = nullptr,
7678*6fee86a4SJeremy Kemp         Event* event = nullptr) const
7679*6fee86a4SJeremy Kemp     {
7680*6fee86a4SJeremy Kemp         cl_event tmp;
7681*6fee86a4SJeremy Kemp         cl_int err = detail::errHandler(
7682*6fee86a4SJeremy Kemp             ::clEnqueueReadBufferRect(
7683*6fee86a4SJeremy Kemp                 object_,
7684*6fee86a4SJeremy Kemp                 buffer(),
7685*6fee86a4SJeremy Kemp                 blocking,
7686*6fee86a4SJeremy Kemp                 buffer_offset.data(),
7687*6fee86a4SJeremy Kemp                 host_offset.data(),
7688*6fee86a4SJeremy Kemp                 region.data(),
7689*6fee86a4SJeremy Kemp                 buffer_row_pitch,
7690*6fee86a4SJeremy Kemp                 buffer_slice_pitch,
7691*6fee86a4SJeremy Kemp                 host_row_pitch,
7692*6fee86a4SJeremy Kemp                 host_slice_pitch,
7693*6fee86a4SJeremy Kemp                 ptr,
7694*6fee86a4SJeremy Kemp                 (events != nullptr) ? (cl_uint) events->size() : 0,
7695*6fee86a4SJeremy Kemp                 (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
7696*6fee86a4SJeremy Kemp                 (event != nullptr) ? &tmp : nullptr),
7697*6fee86a4SJeremy Kemp                 __ENQUEUE_READ_BUFFER_RECT_ERR);
7698*6fee86a4SJeremy Kemp 
7699*6fee86a4SJeremy Kemp         if (event != nullptr && err == CL_SUCCESS)
7700*6fee86a4SJeremy Kemp             *event = tmp;
7701*6fee86a4SJeremy Kemp 
7702*6fee86a4SJeremy Kemp         return err;
7703*6fee86a4SJeremy Kemp     }
7704*6fee86a4SJeremy Kemp 
enqueueReadBufferRect(const Buffer & buffer,cl_bool blocking,const array<size_type,2> & buffer_offset,const array<size_type,2> & host_offset,const array<size_type,2> & region,size_type buffer_row_pitch,size_type buffer_slice_pitch,size_type host_row_pitch,size_type host_slice_pitch,void * ptr,const vector<Event> * events=nullptr,Event * event=nullptr) const7705*6fee86a4SJeremy Kemp     cl_int enqueueReadBufferRect(
7706*6fee86a4SJeremy Kemp         const Buffer& buffer,
7707*6fee86a4SJeremy Kemp         cl_bool blocking,
7708*6fee86a4SJeremy Kemp         const array<size_type, 2>& buffer_offset,
7709*6fee86a4SJeremy Kemp         const array<size_type, 2>& host_offset,
7710*6fee86a4SJeremy Kemp         const array<size_type, 2>& region,
7711*6fee86a4SJeremy Kemp         size_type buffer_row_pitch,
7712*6fee86a4SJeremy Kemp         size_type buffer_slice_pitch,
7713*6fee86a4SJeremy Kemp         size_type host_row_pitch,
7714*6fee86a4SJeremy Kemp         size_type host_slice_pitch,
7715*6fee86a4SJeremy Kemp         void* ptr,
7716*6fee86a4SJeremy Kemp         const vector<Event>* events = nullptr,
7717*6fee86a4SJeremy Kemp         Event* event = nullptr) const
7718*6fee86a4SJeremy Kemp     {
7719*6fee86a4SJeremy Kemp         return enqueueReadBufferRect(
7720*6fee86a4SJeremy Kemp             buffer,
7721*6fee86a4SJeremy Kemp             blocking,
7722*6fee86a4SJeremy Kemp             { buffer_offset[0], buffer_offset[1], 0 },
7723*6fee86a4SJeremy Kemp             { host_offset[0], host_offset[1], 0 },
7724*6fee86a4SJeremy Kemp             { region[0], region[1], 1 },
7725*6fee86a4SJeremy Kemp             buffer_row_pitch,
7726*6fee86a4SJeremy Kemp             buffer_slice_pitch,
7727*6fee86a4SJeremy Kemp             host_row_pitch,
7728*6fee86a4SJeremy Kemp             host_slice_pitch,
7729*6fee86a4SJeremy Kemp             ptr,
7730*6fee86a4SJeremy Kemp             events,
7731*6fee86a4SJeremy Kemp             event);
7732*6fee86a4SJeremy Kemp     }
7733*6fee86a4SJeremy Kemp 
enqueueWriteBufferRect(const Buffer & buffer,cl_bool blocking,const array<size_type,3> & buffer_offset,const array<size_type,3> & host_offset,const array<size_type,3> & region,size_type buffer_row_pitch,size_type buffer_slice_pitch,size_type host_row_pitch,size_type host_slice_pitch,const void * ptr,const vector<Event> * events=nullptr,Event * event=nullptr) const7734*6fee86a4SJeremy Kemp     cl_int enqueueWriteBufferRect(
7735*6fee86a4SJeremy Kemp         const Buffer& buffer,
7736*6fee86a4SJeremy Kemp         cl_bool blocking,
7737*6fee86a4SJeremy Kemp         const array<size_type, 3>& buffer_offset,
7738*6fee86a4SJeremy Kemp         const array<size_type, 3>& host_offset,
7739*6fee86a4SJeremy Kemp         const array<size_type, 3>& region,
7740*6fee86a4SJeremy Kemp         size_type buffer_row_pitch,
7741*6fee86a4SJeremy Kemp         size_type buffer_slice_pitch,
7742*6fee86a4SJeremy Kemp         size_type host_row_pitch,
7743*6fee86a4SJeremy Kemp         size_type host_slice_pitch,
7744*6fee86a4SJeremy Kemp         const void *ptr,
7745*6fee86a4SJeremy Kemp         const vector<Event>* events = nullptr,
7746*6fee86a4SJeremy Kemp         Event* event = nullptr) const
7747*6fee86a4SJeremy Kemp     {
7748*6fee86a4SJeremy Kemp         cl_event tmp;
7749*6fee86a4SJeremy Kemp         cl_int err = detail::errHandler(
7750*6fee86a4SJeremy Kemp             ::clEnqueueWriteBufferRect(
7751*6fee86a4SJeremy Kemp                 object_,
7752*6fee86a4SJeremy Kemp                 buffer(),
7753*6fee86a4SJeremy Kemp                 blocking,
7754*6fee86a4SJeremy Kemp                 buffer_offset.data(),
7755*6fee86a4SJeremy Kemp                 host_offset.data(),
7756*6fee86a4SJeremy Kemp                 region.data(),
7757*6fee86a4SJeremy Kemp                 buffer_row_pitch,
7758*6fee86a4SJeremy Kemp                 buffer_slice_pitch,
7759*6fee86a4SJeremy Kemp                 host_row_pitch,
7760*6fee86a4SJeremy Kemp                 host_slice_pitch,
7761*6fee86a4SJeremy Kemp                 ptr,
7762*6fee86a4SJeremy Kemp                 (events != nullptr) ? (cl_uint) events->size() : 0,
7763*6fee86a4SJeremy Kemp                 (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
7764*6fee86a4SJeremy Kemp                 (event != nullptr) ? &tmp : nullptr),
7765*6fee86a4SJeremy Kemp                 __ENQUEUE_WRITE_BUFFER_RECT_ERR);
7766*6fee86a4SJeremy Kemp 
7767*6fee86a4SJeremy Kemp         if (event != nullptr && err == CL_SUCCESS)
7768*6fee86a4SJeremy Kemp             *event = tmp;
7769*6fee86a4SJeremy Kemp 
7770*6fee86a4SJeremy Kemp         return err;
7771*6fee86a4SJeremy Kemp     }
7772*6fee86a4SJeremy Kemp 
enqueueWriteBufferRect(const Buffer & buffer,cl_bool blocking,const array<size_type,2> & buffer_offset,const array<size_type,2> & host_offset,const array<size_type,2> & region,size_type buffer_row_pitch,size_type buffer_slice_pitch,size_type host_row_pitch,size_type host_slice_pitch,const void * ptr,const vector<Event> * events=nullptr,Event * event=nullptr) const7773*6fee86a4SJeremy Kemp     cl_int enqueueWriteBufferRect(
7774*6fee86a4SJeremy Kemp         const Buffer& buffer,
7775*6fee86a4SJeremy Kemp         cl_bool blocking,
7776*6fee86a4SJeremy Kemp         const array<size_type, 2>& buffer_offset,
7777*6fee86a4SJeremy Kemp         const array<size_type, 2>& host_offset,
7778*6fee86a4SJeremy Kemp         const array<size_type, 2>& region,
7779*6fee86a4SJeremy Kemp         size_type buffer_row_pitch,
7780*6fee86a4SJeremy Kemp         size_type buffer_slice_pitch,
7781*6fee86a4SJeremy Kemp         size_type host_row_pitch,
7782*6fee86a4SJeremy Kemp         size_type host_slice_pitch,
7783*6fee86a4SJeremy Kemp         const void* ptr,
7784*6fee86a4SJeremy Kemp         const vector<Event>* events = nullptr,
7785*6fee86a4SJeremy Kemp         Event* event = nullptr) const
7786*6fee86a4SJeremy Kemp     {
7787*6fee86a4SJeremy Kemp         return enqueueWriteBufferRect(
7788*6fee86a4SJeremy Kemp             buffer,
7789*6fee86a4SJeremy Kemp             blocking,
7790*6fee86a4SJeremy Kemp             { buffer_offset[0], buffer_offset[1], 0 },
7791*6fee86a4SJeremy Kemp             { host_offset[0], host_offset[1], 0 },
7792*6fee86a4SJeremy Kemp             { region[0], region[1], 1 },
7793*6fee86a4SJeremy Kemp             buffer_row_pitch,
7794*6fee86a4SJeremy Kemp             buffer_slice_pitch,
7795*6fee86a4SJeremy Kemp             host_row_pitch,
7796*6fee86a4SJeremy Kemp             host_slice_pitch,
7797*6fee86a4SJeremy Kemp             ptr,
7798*6fee86a4SJeremy Kemp             events,
7799*6fee86a4SJeremy Kemp             event);
7800*6fee86a4SJeremy Kemp     }
7801*6fee86a4SJeremy Kemp 
enqueueCopyBufferRect(const Buffer & src,const Buffer & dst,const array<size_type,3> & src_origin,const array<size_type,3> & dst_origin,const array<size_type,3> & region,size_type src_row_pitch,size_type src_slice_pitch,size_type dst_row_pitch,size_type dst_slice_pitch,const vector<Event> * events=nullptr,Event * event=nullptr) const7802*6fee86a4SJeremy Kemp     cl_int enqueueCopyBufferRect(
7803*6fee86a4SJeremy Kemp         const Buffer& src,
7804*6fee86a4SJeremy Kemp         const Buffer& dst,
7805*6fee86a4SJeremy Kemp         const array<size_type, 3>& src_origin,
7806*6fee86a4SJeremy Kemp         const array<size_type, 3>& dst_origin,
7807*6fee86a4SJeremy Kemp         const array<size_type, 3>& region,
7808*6fee86a4SJeremy Kemp         size_type src_row_pitch,
7809*6fee86a4SJeremy Kemp         size_type src_slice_pitch,
7810*6fee86a4SJeremy Kemp         size_type dst_row_pitch,
7811*6fee86a4SJeremy Kemp         size_type dst_slice_pitch,
7812*6fee86a4SJeremy Kemp         const vector<Event>* events = nullptr,
7813*6fee86a4SJeremy Kemp         Event* event = nullptr) const
7814*6fee86a4SJeremy Kemp     {
7815*6fee86a4SJeremy Kemp         cl_event tmp;
7816*6fee86a4SJeremy Kemp         cl_int err = detail::errHandler(
7817*6fee86a4SJeremy Kemp             ::clEnqueueCopyBufferRect(
7818*6fee86a4SJeremy Kemp                 object_,
7819*6fee86a4SJeremy Kemp                 src(),
7820*6fee86a4SJeremy Kemp                 dst(),
7821*6fee86a4SJeremy Kemp                 src_origin.data(),
7822*6fee86a4SJeremy Kemp                 dst_origin.data(),
7823*6fee86a4SJeremy Kemp                 region.data(),
7824*6fee86a4SJeremy Kemp                 src_row_pitch,
7825*6fee86a4SJeremy Kemp                 src_slice_pitch,
7826*6fee86a4SJeremy Kemp                 dst_row_pitch,
7827*6fee86a4SJeremy Kemp                 dst_slice_pitch,
7828*6fee86a4SJeremy Kemp                 (events != nullptr) ? (cl_uint) events->size() : 0,
7829*6fee86a4SJeremy Kemp                 (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
7830*6fee86a4SJeremy Kemp                 (event != nullptr) ? &tmp : nullptr),
7831*6fee86a4SJeremy Kemp             __ENQEUE_COPY_BUFFER_RECT_ERR);
7832*6fee86a4SJeremy Kemp 
7833*6fee86a4SJeremy Kemp         if (event != nullptr && err == CL_SUCCESS)
7834*6fee86a4SJeremy Kemp             *event = tmp;
7835*6fee86a4SJeremy Kemp 
7836*6fee86a4SJeremy Kemp         return err;
7837*6fee86a4SJeremy Kemp     }
7838*6fee86a4SJeremy Kemp 
enqueueCopyBufferRect(const Buffer & src,const Buffer & dst,const array<size_type,2> & src_origin,const array<size_type,2> & dst_origin,const array<size_type,2> & region,size_type src_row_pitch,size_type src_slice_pitch,size_type dst_row_pitch,size_type dst_slice_pitch,const vector<Event> * events=nullptr,Event * event=nullptr) const7839*6fee86a4SJeremy Kemp     cl_int enqueueCopyBufferRect(
7840*6fee86a4SJeremy Kemp         const Buffer& src,
7841*6fee86a4SJeremy Kemp         const Buffer& dst,
7842*6fee86a4SJeremy Kemp         const array<size_type, 2>& src_origin,
7843*6fee86a4SJeremy Kemp         const array<size_type, 2>& dst_origin,
7844*6fee86a4SJeremy Kemp         const array<size_type, 2>& region,
7845*6fee86a4SJeremy Kemp         size_type src_row_pitch,
7846*6fee86a4SJeremy Kemp         size_type src_slice_pitch,
7847*6fee86a4SJeremy Kemp         size_type dst_row_pitch,
7848*6fee86a4SJeremy Kemp         size_type dst_slice_pitch,
7849*6fee86a4SJeremy Kemp         const vector<Event>* events = nullptr,
7850*6fee86a4SJeremy Kemp         Event* event = nullptr) const
7851*6fee86a4SJeremy Kemp     {
7852*6fee86a4SJeremy Kemp         return enqueueCopyBufferRect(
7853*6fee86a4SJeremy Kemp             src,
7854*6fee86a4SJeremy Kemp             dst,
7855*6fee86a4SJeremy Kemp             { src_origin[0], src_origin[1], 0 },
7856*6fee86a4SJeremy Kemp             { dst_origin[0], dst_origin[1], 0 },
7857*6fee86a4SJeremy Kemp             { region[0], region[1], 1 },
7858*6fee86a4SJeremy Kemp             src_row_pitch,
7859*6fee86a4SJeremy Kemp             src_slice_pitch,
7860*6fee86a4SJeremy Kemp             dst_row_pitch,
7861*6fee86a4SJeremy Kemp             dst_slice_pitch,
7862*6fee86a4SJeremy Kemp             events,
7863*6fee86a4SJeremy Kemp             event);
7864*6fee86a4SJeremy Kemp     }
7865*6fee86a4SJeremy Kemp 
7866*6fee86a4SJeremy Kemp #endif // CL_HPP_TARGET_OPENCL_VERSION >= 110
7867*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 120
7868*6fee86a4SJeremy Kemp     /**
7869*6fee86a4SJeremy Kemp      * Enqueue a command to fill a buffer object with a pattern
7870*6fee86a4SJeremy Kemp      * of a given size. The pattern is specified as a vector type.
7871*6fee86a4SJeremy Kemp      * \tparam PatternType The datatype of the pattern field.
7872*6fee86a4SJeremy Kemp      *     The pattern type must be an accepted OpenCL data type.
7873*6fee86a4SJeremy Kemp      * \tparam offset Is the offset in bytes into the buffer at
7874*6fee86a4SJeremy Kemp      *     which to start filling. This must be a multiple of
7875*6fee86a4SJeremy Kemp      *     the pattern size.
7876*6fee86a4SJeremy Kemp      * \tparam size Is the size in bytes of the region to fill.
7877*6fee86a4SJeremy Kemp      *     This must be a multiple of the pattern size.
7878*6fee86a4SJeremy Kemp      */
7879*6fee86a4SJeremy Kemp     template<typename PatternType>
enqueueFillBuffer(const Buffer & buffer,PatternType pattern,size_type offset,size_type size,const vector<Event> * events=nullptr,Event * event=nullptr) const7880*6fee86a4SJeremy Kemp     cl_int enqueueFillBuffer(
7881*6fee86a4SJeremy Kemp         const Buffer& buffer,
7882*6fee86a4SJeremy Kemp         PatternType pattern,
7883*6fee86a4SJeremy Kemp         size_type offset,
7884*6fee86a4SJeremy Kemp         size_type size,
7885*6fee86a4SJeremy Kemp         const vector<Event>* events = nullptr,
7886*6fee86a4SJeremy Kemp         Event* event = nullptr) const
7887*6fee86a4SJeremy Kemp     {
7888*6fee86a4SJeremy Kemp         cl_event tmp;
7889*6fee86a4SJeremy Kemp         cl_int err = detail::errHandler(
7890*6fee86a4SJeremy Kemp             ::clEnqueueFillBuffer(
7891*6fee86a4SJeremy Kemp                 object_,
7892*6fee86a4SJeremy Kemp                 buffer(),
7893*6fee86a4SJeremy Kemp                 static_cast<void*>(&pattern),
7894*6fee86a4SJeremy Kemp                 sizeof(PatternType),
7895*6fee86a4SJeremy Kemp                 offset,
7896*6fee86a4SJeremy Kemp                 size,
7897*6fee86a4SJeremy Kemp                 (events != nullptr) ? (cl_uint) events->size() : 0,
7898*6fee86a4SJeremy Kemp                 (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
7899*6fee86a4SJeremy Kemp                 (event != nullptr) ? &tmp : nullptr),
7900*6fee86a4SJeremy Kemp                 __ENQUEUE_FILL_BUFFER_ERR);
7901*6fee86a4SJeremy Kemp 
7902*6fee86a4SJeremy Kemp         if (event != nullptr && err == CL_SUCCESS)
7903*6fee86a4SJeremy Kemp             *event = tmp;
7904*6fee86a4SJeremy Kemp 
7905*6fee86a4SJeremy Kemp         return err;
7906*6fee86a4SJeremy Kemp     }
7907*6fee86a4SJeremy Kemp #endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
7908*6fee86a4SJeremy Kemp 
enqueueReadImage(const Image & image,cl_bool blocking,const array<size_type,3> & origin,const array<size_type,3> & region,size_type row_pitch,size_type slice_pitch,void * ptr,const vector<Event> * events=nullptr,Event * event=nullptr) const7909*6fee86a4SJeremy Kemp     cl_int enqueueReadImage(
7910*6fee86a4SJeremy Kemp         const Image& image,
7911*6fee86a4SJeremy Kemp         cl_bool blocking,
7912*6fee86a4SJeremy Kemp         const array<size_type, 3>& origin,
7913*6fee86a4SJeremy Kemp         const array<size_type, 3>& region,
7914*6fee86a4SJeremy Kemp         size_type row_pitch,
7915*6fee86a4SJeremy Kemp         size_type slice_pitch,
7916*6fee86a4SJeremy Kemp         void* ptr,
7917*6fee86a4SJeremy Kemp         const vector<Event>* events = nullptr,
7918*6fee86a4SJeremy Kemp         Event* event = nullptr) const
7919*6fee86a4SJeremy Kemp     {
7920*6fee86a4SJeremy Kemp         cl_event tmp;
7921*6fee86a4SJeremy Kemp         cl_int err = detail::errHandler(
7922*6fee86a4SJeremy Kemp             ::clEnqueueReadImage(
7923*6fee86a4SJeremy Kemp                 object_,
7924*6fee86a4SJeremy Kemp                 image(),
7925*6fee86a4SJeremy Kemp                 blocking,
7926*6fee86a4SJeremy Kemp                 origin.data(),
7927*6fee86a4SJeremy Kemp                 region.data(),
7928*6fee86a4SJeremy Kemp                 row_pitch,
7929*6fee86a4SJeremy Kemp                 slice_pitch,
7930*6fee86a4SJeremy Kemp                 ptr,
7931*6fee86a4SJeremy Kemp                 (events != nullptr) ? (cl_uint) events->size() : 0,
7932*6fee86a4SJeremy Kemp                 (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
7933*6fee86a4SJeremy Kemp                 (event != nullptr) ? &tmp : nullptr),
7934*6fee86a4SJeremy Kemp             __ENQUEUE_READ_IMAGE_ERR);
7935*6fee86a4SJeremy Kemp 
7936*6fee86a4SJeremy Kemp         if (event != nullptr && err == CL_SUCCESS)
7937*6fee86a4SJeremy Kemp             *event = tmp;
7938*6fee86a4SJeremy Kemp 
7939*6fee86a4SJeremy Kemp         return err;
7940*6fee86a4SJeremy Kemp     }
7941*6fee86a4SJeremy Kemp 
enqueueReadImage(const Image & image,cl_bool blocking,const array<size_type,2> & origin,const array<size_type,2> & region,size_type row_pitch,size_type slice_pitch,void * ptr,const vector<Event> * events=nullptr,Event * event=nullptr) const7942*6fee86a4SJeremy Kemp     cl_int enqueueReadImage(
7943*6fee86a4SJeremy Kemp         const Image& image,
7944*6fee86a4SJeremy Kemp         cl_bool blocking,
7945*6fee86a4SJeremy Kemp         const array<size_type, 2>& origin,
7946*6fee86a4SJeremy Kemp         const array<size_type, 2>& region,
7947*6fee86a4SJeremy Kemp         size_type row_pitch,
7948*6fee86a4SJeremy Kemp         size_type slice_pitch,
7949*6fee86a4SJeremy Kemp         void* ptr,
7950*6fee86a4SJeremy Kemp         const vector<Event>* events = nullptr,
7951*6fee86a4SJeremy Kemp         Event* event = nullptr) const
7952*6fee86a4SJeremy Kemp     {
7953*6fee86a4SJeremy Kemp         return enqueueReadImage(
7954*6fee86a4SJeremy Kemp             image,
7955*6fee86a4SJeremy Kemp             blocking,
7956*6fee86a4SJeremy Kemp             { origin[0], origin[1], 0 },
7957*6fee86a4SJeremy Kemp             { region[0], region[1], 1 },
7958*6fee86a4SJeremy Kemp             row_pitch,
7959*6fee86a4SJeremy Kemp             slice_pitch,
7960*6fee86a4SJeremy Kemp             ptr,
7961*6fee86a4SJeremy Kemp             events,
7962*6fee86a4SJeremy Kemp             event);
7963*6fee86a4SJeremy Kemp     }
7964*6fee86a4SJeremy Kemp 
enqueueWriteImage(const Image & image,cl_bool blocking,const array<size_type,3> & origin,const array<size_type,3> & region,size_type row_pitch,size_type slice_pitch,const void * ptr,const vector<Event> * events=nullptr,Event * event=nullptr) const7965*6fee86a4SJeremy Kemp     cl_int enqueueWriteImage(
7966*6fee86a4SJeremy Kemp         const Image& image,
7967*6fee86a4SJeremy Kemp         cl_bool blocking,
7968*6fee86a4SJeremy Kemp         const array<size_type, 3>& origin,
7969*6fee86a4SJeremy Kemp         const array<size_type, 3>& region,
7970*6fee86a4SJeremy Kemp         size_type row_pitch,
7971*6fee86a4SJeremy Kemp         size_type slice_pitch,
7972*6fee86a4SJeremy Kemp         const void* ptr,
7973*6fee86a4SJeremy Kemp         const vector<Event>* events = nullptr,
7974*6fee86a4SJeremy Kemp         Event* event = nullptr) const
7975*6fee86a4SJeremy Kemp     {
7976*6fee86a4SJeremy Kemp         cl_event tmp;
7977*6fee86a4SJeremy Kemp         cl_int err = detail::errHandler(
7978*6fee86a4SJeremy Kemp             ::clEnqueueWriteImage(
7979*6fee86a4SJeremy Kemp                 object_,
7980*6fee86a4SJeremy Kemp                 image(),
7981*6fee86a4SJeremy Kemp                 blocking,
7982*6fee86a4SJeremy Kemp                 origin.data(),
7983*6fee86a4SJeremy Kemp                 region.data(),
7984*6fee86a4SJeremy Kemp                 row_pitch,
7985*6fee86a4SJeremy Kemp                 slice_pitch,
7986*6fee86a4SJeremy Kemp                 ptr,
7987*6fee86a4SJeremy Kemp                 (events != nullptr) ? (cl_uint) events->size() : 0,
7988*6fee86a4SJeremy Kemp                 (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
7989*6fee86a4SJeremy Kemp                 (event != nullptr) ? &tmp : nullptr),
7990*6fee86a4SJeremy Kemp             __ENQUEUE_WRITE_IMAGE_ERR);
7991*6fee86a4SJeremy Kemp 
7992*6fee86a4SJeremy Kemp         if (event != nullptr && err == CL_SUCCESS)
7993*6fee86a4SJeremy Kemp             *event = tmp;
7994*6fee86a4SJeremy Kemp 
7995*6fee86a4SJeremy Kemp         return err;
7996*6fee86a4SJeremy Kemp     }
7997*6fee86a4SJeremy Kemp 
enqueueWriteImage(const Image & image,cl_bool blocking,const array<size_type,2> & origin,const array<size_type,2> & region,size_type row_pitch,size_type slice_pitch,const void * ptr,const vector<Event> * events=nullptr,Event * event=nullptr) const7998*6fee86a4SJeremy Kemp     cl_int enqueueWriteImage(
7999*6fee86a4SJeremy Kemp         const Image& image,
8000*6fee86a4SJeremy Kemp         cl_bool blocking,
8001*6fee86a4SJeremy Kemp         const array<size_type, 2>& origin,
8002*6fee86a4SJeremy Kemp         const array<size_type, 2>& region,
8003*6fee86a4SJeremy Kemp         size_type row_pitch,
8004*6fee86a4SJeremy Kemp         size_type slice_pitch,
8005*6fee86a4SJeremy Kemp         const void* ptr,
8006*6fee86a4SJeremy Kemp         const vector<Event>* events = nullptr,
8007*6fee86a4SJeremy Kemp         Event* event = nullptr) const
8008*6fee86a4SJeremy Kemp     {
8009*6fee86a4SJeremy Kemp         return enqueueWriteImage(
8010*6fee86a4SJeremy Kemp             image,
8011*6fee86a4SJeremy Kemp             blocking,
8012*6fee86a4SJeremy Kemp             { origin[0], origin[1], 0 },
8013*6fee86a4SJeremy Kemp             { region[0], region[1], 1 },
8014*6fee86a4SJeremy Kemp             row_pitch,
8015*6fee86a4SJeremy Kemp             slice_pitch,
8016*6fee86a4SJeremy Kemp             ptr,
8017*6fee86a4SJeremy Kemp             events,
8018*6fee86a4SJeremy Kemp             event);
8019*6fee86a4SJeremy Kemp     }
8020*6fee86a4SJeremy Kemp 
enqueueCopyImage(const Image & src,const Image & dst,const array<size_type,3> & src_origin,const array<size_type,3> & dst_origin,const array<size_type,3> & region,const vector<Event> * events=nullptr,Event * event=nullptr) const8021*6fee86a4SJeremy Kemp     cl_int enqueueCopyImage(
8022*6fee86a4SJeremy Kemp         const Image& src,
8023*6fee86a4SJeremy Kemp         const Image& dst,
8024*6fee86a4SJeremy Kemp         const array<size_type, 3>& src_origin,
8025*6fee86a4SJeremy Kemp         const array<size_type, 3>& dst_origin,
8026*6fee86a4SJeremy Kemp         const array<size_type, 3>& region,
8027*6fee86a4SJeremy Kemp         const vector<Event>* events = nullptr,
8028*6fee86a4SJeremy Kemp         Event* event = nullptr) const
8029*6fee86a4SJeremy Kemp     {
8030*6fee86a4SJeremy Kemp         cl_event tmp;
8031*6fee86a4SJeremy Kemp         cl_int err = detail::errHandler(
8032*6fee86a4SJeremy Kemp             ::clEnqueueCopyImage(
8033*6fee86a4SJeremy Kemp                 object_,
8034*6fee86a4SJeremy Kemp                 src(),
8035*6fee86a4SJeremy Kemp                 dst(),
8036*6fee86a4SJeremy Kemp                 src_origin.data(),
8037*6fee86a4SJeremy Kemp                 dst_origin.data(),
8038*6fee86a4SJeremy Kemp                 region.data(),
8039*6fee86a4SJeremy Kemp                 (events != nullptr) ? (cl_uint) events->size() : 0,
8040*6fee86a4SJeremy Kemp                 (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
8041*6fee86a4SJeremy Kemp                 (event != nullptr) ? &tmp : nullptr),
8042*6fee86a4SJeremy Kemp             __ENQUEUE_COPY_IMAGE_ERR);
8043*6fee86a4SJeremy Kemp 
8044*6fee86a4SJeremy Kemp         if (event != nullptr && err == CL_SUCCESS)
8045*6fee86a4SJeremy Kemp             *event = tmp;
8046*6fee86a4SJeremy Kemp 
8047*6fee86a4SJeremy Kemp         return err;
8048*6fee86a4SJeremy Kemp     }
8049*6fee86a4SJeremy Kemp 
enqueueCopyImage(const Image & src,const Image & dst,const array<size_type,2> & src_origin,const array<size_type,2> & dst_origin,const array<size_type,2> & region,const vector<Event> * events=nullptr,Event * event=nullptr) const8050*6fee86a4SJeremy Kemp     cl_int enqueueCopyImage(
8051*6fee86a4SJeremy Kemp         const Image& src,
8052*6fee86a4SJeremy Kemp         const Image& dst,
8053*6fee86a4SJeremy Kemp         const array<size_type, 2>& src_origin,
8054*6fee86a4SJeremy Kemp         const array<size_type, 2>& dst_origin,
8055*6fee86a4SJeremy Kemp         const array<size_type, 2>& region,
8056*6fee86a4SJeremy Kemp         const vector<Event>* events = nullptr,
8057*6fee86a4SJeremy Kemp         Event* event = nullptr) const
8058*6fee86a4SJeremy Kemp     {
8059*6fee86a4SJeremy Kemp         return enqueueCopyImage(
8060*6fee86a4SJeremy Kemp             src,
8061*6fee86a4SJeremy Kemp             dst,
8062*6fee86a4SJeremy Kemp             { src_origin[0], src_origin[1], 0 },
8063*6fee86a4SJeremy Kemp             { dst_origin[0], dst_origin[1], 0 },
8064*6fee86a4SJeremy Kemp             { region[0], region[1], 1 },
8065*6fee86a4SJeremy Kemp             events,
8066*6fee86a4SJeremy Kemp             event);
8067*6fee86a4SJeremy Kemp     }
8068*6fee86a4SJeremy Kemp 
8069*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 120
8070*6fee86a4SJeremy Kemp     /**
8071*6fee86a4SJeremy Kemp      * Enqueue a command to fill an image object with a specified color.
8072*6fee86a4SJeremy Kemp      * \param fillColor is the color to use to fill the image.
8073*6fee86a4SJeremy Kemp      *     This is a four component RGBA floating-point, signed integer
8074*6fee86a4SJeremy Kemp      *     or unsigned integer color value if  the image channel data
8075*6fee86a4SJeremy Kemp      *     type is an unnormalized signed integer type.
8076*6fee86a4SJeremy Kemp      */
8077*6fee86a4SJeremy Kemp     template <typename T>
8078*6fee86a4SJeremy Kemp     typename std::enable_if<std::is_same<T, cl_float4>::value ||
8079*6fee86a4SJeremy Kemp                             std::is_same<T, cl_int4  >::value ||
8080*6fee86a4SJeremy Kemp                             std::is_same<T, cl_uint4 >::value,
8081*6fee86a4SJeremy Kemp                             cl_int>::type
enqueueFillImage(const Image & image,T fillColor,const array<size_type,3> & origin,const array<size_type,3> & region,const vector<Event> * events=nullptr,Event * event=nullptr) const8082*6fee86a4SJeremy Kemp      enqueueFillImage(
8083*6fee86a4SJeremy Kemp          const Image& image,
8084*6fee86a4SJeremy Kemp          T fillColor,
8085*6fee86a4SJeremy Kemp          const array<size_type, 3>& origin,
8086*6fee86a4SJeremy Kemp          const array<size_type, 3>& region,
8087*6fee86a4SJeremy Kemp          const vector<Event>* events = nullptr,
8088*6fee86a4SJeremy Kemp          Event* event = nullptr) const
8089*6fee86a4SJeremy Kemp     {
8090*6fee86a4SJeremy Kemp         cl_event tmp;
8091*6fee86a4SJeremy Kemp         cl_int err = detail::errHandler(
8092*6fee86a4SJeremy Kemp             ::clEnqueueFillImage(
8093*6fee86a4SJeremy Kemp                 object_,
8094*6fee86a4SJeremy Kemp                 image(),
8095*6fee86a4SJeremy Kemp                 static_cast<void*>(&fillColor),
8096*6fee86a4SJeremy Kemp                 origin.data(),
8097*6fee86a4SJeremy Kemp                 region.data(),
8098*6fee86a4SJeremy Kemp                 (events != nullptr) ? (cl_uint)events->size() : 0,
8099*6fee86a4SJeremy Kemp                 (events != nullptr && events->size() > 0) ? (cl_event*)&events->front() : NULL,
8100*6fee86a4SJeremy Kemp                 (event != NULL) ? &tmp : nullptr),
8101*6fee86a4SJeremy Kemp             __ENQUEUE_FILL_IMAGE_ERR);
8102*6fee86a4SJeremy Kemp 
8103*6fee86a4SJeremy Kemp         if (event != nullptr && err == CL_SUCCESS) *event = tmp;
8104*6fee86a4SJeremy Kemp 
8105*6fee86a4SJeremy Kemp         return err;
8106*6fee86a4SJeremy Kemp     }
8107*6fee86a4SJeremy Kemp 
8108*6fee86a4SJeremy Kemp    /**
8109*6fee86a4SJeremy Kemp      * Enqueue a command to fill an image object with a specified color.
8110*6fee86a4SJeremy Kemp      * \param fillColor is the color to use to fill the image.
8111*6fee86a4SJeremy Kemp      *     This is a four component RGBA floating-point, signed integer
8112*6fee86a4SJeremy Kemp      *     or unsigned integer color value if  the image channel data
8113*6fee86a4SJeremy Kemp      *     type is an unnormalized signed integer type.
8114*6fee86a4SJeremy Kemp      */
8115*6fee86a4SJeremy Kemp     template <typename T>
8116*6fee86a4SJeremy Kemp     typename std::enable_if<std::is_same<T, cl_float4>::value ||
8117*6fee86a4SJeremy Kemp                             std::is_same<T, cl_int4  >::value ||
8118*6fee86a4SJeremy Kemp                             std::is_same<T, cl_uint4 >::value, cl_int>::type
enqueueFillImage(const Image & image,T fillColor,const array<size_type,2> & origin,const array<size_type,2> & region,const vector<Event> * events=nullptr,Event * event=nullptr) const8119*6fee86a4SJeremy Kemp     enqueueFillImage(
8120*6fee86a4SJeremy Kemp         const Image& image,
8121*6fee86a4SJeremy Kemp         T fillColor,
8122*6fee86a4SJeremy Kemp         const array<size_type, 2>& origin,
8123*6fee86a4SJeremy Kemp         const array<size_type, 2>& region,
8124*6fee86a4SJeremy Kemp         const vector<Event>* events = nullptr,
8125*6fee86a4SJeremy Kemp         Event* event = nullptr) const
8126*6fee86a4SJeremy Kemp     {
8127*6fee86a4SJeremy Kemp         return enqueueFillImage(
8128*6fee86a4SJeremy Kemp             image,
8129*6fee86a4SJeremy Kemp             fillColor,
8130*6fee86a4SJeremy Kemp             { origin[0], origin[1], 0 },
8131*6fee86a4SJeremy Kemp             { region[0], region[1], 1 },
8132*6fee86a4SJeremy Kemp             events,
8133*6fee86a4SJeremy Kemp             event
8134*6fee86a4SJeremy Kemp             );
8135*6fee86a4SJeremy Kemp     }
8136*6fee86a4SJeremy Kemp #endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
8137*6fee86a4SJeremy Kemp 
enqueueCopyImageToBuffer(const Image & src,const Buffer & dst,const array<size_type,3> & src_origin,const array<size_type,3> & region,size_type dst_offset,const vector<Event> * events=nullptr,Event * event=nullptr) const8138*6fee86a4SJeremy Kemp     cl_int enqueueCopyImageToBuffer(
8139*6fee86a4SJeremy Kemp         const Image& src,
8140*6fee86a4SJeremy Kemp         const Buffer& dst,
8141*6fee86a4SJeremy Kemp         const array<size_type, 3>& src_origin,
8142*6fee86a4SJeremy Kemp         const array<size_type, 3>& region,
8143*6fee86a4SJeremy Kemp         size_type dst_offset,
8144*6fee86a4SJeremy Kemp         const vector<Event>* events = nullptr,
8145*6fee86a4SJeremy Kemp         Event* event = nullptr) const
8146*6fee86a4SJeremy Kemp     {
8147*6fee86a4SJeremy Kemp         cl_event tmp;
8148*6fee86a4SJeremy Kemp         cl_int err = detail::errHandler(
8149*6fee86a4SJeremy Kemp             ::clEnqueueCopyImageToBuffer(
8150*6fee86a4SJeremy Kemp                 object_,
8151*6fee86a4SJeremy Kemp                 src(),
8152*6fee86a4SJeremy Kemp                 dst(),
8153*6fee86a4SJeremy Kemp                 src_origin.data(),
8154*6fee86a4SJeremy Kemp                 region.data(),
8155*6fee86a4SJeremy Kemp                 dst_offset,
8156*6fee86a4SJeremy Kemp                 (events != nullptr) ? (cl_uint) events->size() : 0,
8157*6fee86a4SJeremy Kemp                 (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
8158*6fee86a4SJeremy Kemp                 (event != nullptr) ? &tmp : nullptr),
8159*6fee86a4SJeremy Kemp             __ENQUEUE_COPY_IMAGE_TO_BUFFER_ERR);
8160*6fee86a4SJeremy Kemp 
8161*6fee86a4SJeremy Kemp         if (event != nullptr && err == CL_SUCCESS)
8162*6fee86a4SJeremy Kemp             *event = tmp;
8163*6fee86a4SJeremy Kemp 
8164*6fee86a4SJeremy Kemp         return err;
8165*6fee86a4SJeremy Kemp     }
8166*6fee86a4SJeremy Kemp 
enqueueCopyImageToBuffer(const Image & src,const Buffer & dst,const array<size_type,2> & src_origin,const array<size_type,2> & region,size_type dst_offset,const vector<Event> * events=nullptr,Event * event=nullptr) const8167*6fee86a4SJeremy Kemp     cl_int enqueueCopyImageToBuffer(
8168*6fee86a4SJeremy Kemp         const Image& src,
8169*6fee86a4SJeremy Kemp         const Buffer& dst,
8170*6fee86a4SJeremy Kemp         const array<size_type, 2>& src_origin,
8171*6fee86a4SJeremy Kemp         const array<size_type, 2>& region,
8172*6fee86a4SJeremy Kemp         size_type dst_offset,
8173*6fee86a4SJeremy Kemp         const vector<Event>* events = nullptr,
8174*6fee86a4SJeremy Kemp         Event* event = nullptr) const
8175*6fee86a4SJeremy Kemp     {
8176*6fee86a4SJeremy Kemp         return enqueueCopyImageToBuffer(
8177*6fee86a4SJeremy Kemp             src,
8178*6fee86a4SJeremy Kemp             dst,
8179*6fee86a4SJeremy Kemp             { src_origin[0], src_origin[1], 0 },
8180*6fee86a4SJeremy Kemp             { region[0], region[1], 1 },
8181*6fee86a4SJeremy Kemp             dst_offset,
8182*6fee86a4SJeremy Kemp             events,
8183*6fee86a4SJeremy Kemp             event);
8184*6fee86a4SJeremy Kemp     }
8185*6fee86a4SJeremy Kemp 
enqueueCopyBufferToImage(const Buffer & src,const Image & dst,size_type src_offset,const array<size_type,3> & dst_origin,const array<size_type,3> & region,const vector<Event> * events=nullptr,Event * event=nullptr) const8186*6fee86a4SJeremy Kemp     cl_int enqueueCopyBufferToImage(
8187*6fee86a4SJeremy Kemp         const Buffer& src,
8188*6fee86a4SJeremy Kemp         const Image& dst,
8189*6fee86a4SJeremy Kemp         size_type src_offset,
8190*6fee86a4SJeremy Kemp         const array<size_type, 3>& dst_origin,
8191*6fee86a4SJeremy Kemp         const array<size_type, 3>& region,
8192*6fee86a4SJeremy Kemp         const vector<Event>* events = nullptr,
8193*6fee86a4SJeremy Kemp         Event* event = nullptr) const
8194*6fee86a4SJeremy Kemp     {
8195*6fee86a4SJeremy Kemp         cl_event tmp;
8196*6fee86a4SJeremy Kemp         cl_int err = detail::errHandler(
8197*6fee86a4SJeremy Kemp             ::clEnqueueCopyBufferToImage(
8198*6fee86a4SJeremy Kemp                 object_,
8199*6fee86a4SJeremy Kemp                 src(),
8200*6fee86a4SJeremy Kemp                 dst(),
8201*6fee86a4SJeremy Kemp                 src_offset,
8202*6fee86a4SJeremy Kemp                 dst_origin.data(),
8203*6fee86a4SJeremy Kemp                 region.data(),
8204*6fee86a4SJeremy Kemp                 (events != nullptr) ? (cl_uint) events->size() : 0,
8205*6fee86a4SJeremy Kemp                 (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
8206*6fee86a4SJeremy Kemp                 (event != nullptr) ? &tmp : nullptr),
8207*6fee86a4SJeremy Kemp             __ENQUEUE_COPY_BUFFER_TO_IMAGE_ERR);
8208*6fee86a4SJeremy Kemp 
8209*6fee86a4SJeremy Kemp         if (event != nullptr && err == CL_SUCCESS)
8210*6fee86a4SJeremy Kemp             *event = tmp;
8211*6fee86a4SJeremy Kemp 
8212*6fee86a4SJeremy Kemp         return err;
8213*6fee86a4SJeremy Kemp     }
8214*6fee86a4SJeremy Kemp 
enqueueCopyBufferToImage(const Buffer & src,const Image & dst,size_type src_offset,const array<size_type,2> & dst_origin,const array<size_type,2> & region,const vector<Event> * events=nullptr,Event * event=nullptr) const8215*6fee86a4SJeremy Kemp     cl_int enqueueCopyBufferToImage(
8216*6fee86a4SJeremy Kemp         const Buffer& src,
8217*6fee86a4SJeremy Kemp         const Image& dst,
8218*6fee86a4SJeremy Kemp         size_type src_offset,
8219*6fee86a4SJeremy Kemp         const array<size_type, 2>& dst_origin,
8220*6fee86a4SJeremy Kemp         const array<size_type, 2>& region,
8221*6fee86a4SJeremy Kemp         const vector<Event>* events = nullptr,
8222*6fee86a4SJeremy Kemp         Event* event = nullptr) const
8223*6fee86a4SJeremy Kemp     {
8224*6fee86a4SJeremy Kemp         return enqueueCopyBufferToImage(
8225*6fee86a4SJeremy Kemp             src,
8226*6fee86a4SJeremy Kemp             dst,
8227*6fee86a4SJeremy Kemp             src_offset,
8228*6fee86a4SJeremy Kemp             { dst_origin[0], dst_origin[1], 0 },
8229*6fee86a4SJeremy Kemp             { region[0], region[1], 1 },
8230*6fee86a4SJeremy Kemp             events,
8231*6fee86a4SJeremy Kemp             event);
8232*6fee86a4SJeremy Kemp     }
8233*6fee86a4SJeremy Kemp 
enqueueMapBuffer(const Buffer & buffer,cl_bool blocking,cl_map_flags flags,size_type offset,size_type size,const vector<Event> * events=nullptr,Event * event=nullptr,cl_int * err=nullptr) const8234*6fee86a4SJeremy Kemp     void* enqueueMapBuffer(
8235*6fee86a4SJeremy Kemp         const Buffer& buffer,
8236*6fee86a4SJeremy Kemp         cl_bool blocking,
8237*6fee86a4SJeremy Kemp         cl_map_flags flags,
8238*6fee86a4SJeremy Kemp         size_type offset,
8239*6fee86a4SJeremy Kemp         size_type size,
8240*6fee86a4SJeremy Kemp         const vector<Event>* events = nullptr,
8241*6fee86a4SJeremy Kemp         Event* event = nullptr,
8242*6fee86a4SJeremy Kemp         cl_int* err = nullptr) const
8243*6fee86a4SJeremy Kemp     {
8244*6fee86a4SJeremy Kemp         cl_event tmp;
8245*6fee86a4SJeremy Kemp         cl_int error;
8246*6fee86a4SJeremy Kemp         void * result = ::clEnqueueMapBuffer(
8247*6fee86a4SJeremy Kemp             object_, buffer(), blocking, flags, offset, size,
8248*6fee86a4SJeremy Kemp             (events != nullptr) ? (cl_uint) events->size() : 0,
8249*6fee86a4SJeremy Kemp             (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
8250*6fee86a4SJeremy Kemp             (event != nullptr) ? &tmp : nullptr,
8251*6fee86a4SJeremy Kemp             &error);
8252*6fee86a4SJeremy Kemp 
8253*6fee86a4SJeremy Kemp         detail::errHandler(error, __ENQUEUE_MAP_BUFFER_ERR);
8254*6fee86a4SJeremy Kemp         if (err != nullptr) {
8255*6fee86a4SJeremy Kemp             *err = error;
8256*6fee86a4SJeremy Kemp         }
8257*6fee86a4SJeremy Kemp         if (event != nullptr && error == CL_SUCCESS)
8258*6fee86a4SJeremy Kemp             *event = tmp;
8259*6fee86a4SJeremy Kemp 
8260*6fee86a4SJeremy Kemp         return result;
8261*6fee86a4SJeremy Kemp     }
8262*6fee86a4SJeremy Kemp 
enqueueMapImage(const Image & image,cl_bool blocking,cl_map_flags flags,const array<size_type,3> & origin,const array<size_type,3> & region,size_type * row_pitch,size_type * slice_pitch,const vector<Event> * events=nullptr,Event * event=nullptr,cl_int * err=nullptr) const8263*6fee86a4SJeremy Kemp     void* enqueueMapImage(
8264*6fee86a4SJeremy Kemp         const Image& image,
8265*6fee86a4SJeremy Kemp         cl_bool blocking,
8266*6fee86a4SJeremy Kemp         cl_map_flags flags,
8267*6fee86a4SJeremy Kemp         const array<size_type, 3>& origin,
8268*6fee86a4SJeremy Kemp         const array<size_type, 3>& region,
8269*6fee86a4SJeremy Kemp         size_type * row_pitch,
8270*6fee86a4SJeremy Kemp         size_type * slice_pitch,
8271*6fee86a4SJeremy Kemp         const vector<Event>* events = nullptr,
8272*6fee86a4SJeremy Kemp         Event* event = nullptr,
8273*6fee86a4SJeremy Kemp         cl_int* err = nullptr) const
8274*6fee86a4SJeremy Kemp     {
8275*6fee86a4SJeremy Kemp         cl_event tmp;
8276*6fee86a4SJeremy Kemp         cl_int error;
8277*6fee86a4SJeremy Kemp         void * result = ::clEnqueueMapImage(
8278*6fee86a4SJeremy Kemp             object_, image(), blocking, flags,
8279*6fee86a4SJeremy Kemp             origin.data(),
8280*6fee86a4SJeremy Kemp             region.data(),
8281*6fee86a4SJeremy Kemp             row_pitch, slice_pitch,
8282*6fee86a4SJeremy Kemp             (events != nullptr) ? (cl_uint) events->size() : 0,
8283*6fee86a4SJeremy Kemp             (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
8284*6fee86a4SJeremy Kemp             (event != nullptr) ? &tmp : nullptr,
8285*6fee86a4SJeremy Kemp             &error);
8286*6fee86a4SJeremy Kemp 
8287*6fee86a4SJeremy Kemp         detail::errHandler(error, __ENQUEUE_MAP_IMAGE_ERR);
8288*6fee86a4SJeremy Kemp         if (err != nullptr) {
8289*6fee86a4SJeremy Kemp               *err = error;
8290*6fee86a4SJeremy Kemp         }
8291*6fee86a4SJeremy Kemp         if (event != nullptr && error == CL_SUCCESS)
8292*6fee86a4SJeremy Kemp             *event = tmp;
8293*6fee86a4SJeremy Kemp         return result;
8294*6fee86a4SJeremy Kemp     }
8295*6fee86a4SJeremy Kemp 
enqueueMapImage(const Image & image,cl_bool blocking,cl_map_flags flags,const array<size_type,2> & origin,const array<size_type,2> & region,size_type * row_pitch,size_type * slice_pitch,const vector<Event> * events=nullptr,Event * event=nullptr,cl_int * err=nullptr) const8296*6fee86a4SJeremy Kemp     void* enqueueMapImage(
8297*6fee86a4SJeremy Kemp          const Image& image,
8298*6fee86a4SJeremy Kemp          cl_bool blocking,
8299*6fee86a4SJeremy Kemp          cl_map_flags flags,
8300*6fee86a4SJeremy Kemp          const array<size_type, 2>& origin,
8301*6fee86a4SJeremy Kemp          const array<size_type, 2>& region,
8302*6fee86a4SJeremy Kemp          size_type* row_pitch,
8303*6fee86a4SJeremy Kemp          size_type* slice_pitch,
8304*6fee86a4SJeremy Kemp          const vector<Event>* events = nullptr,
8305*6fee86a4SJeremy Kemp          Event* event = nullptr,
8306*6fee86a4SJeremy Kemp          cl_int* err = nullptr) const
8307*6fee86a4SJeremy Kemp     {
8308*6fee86a4SJeremy Kemp         return enqueueMapImage(image, blocking, flags,
8309*6fee86a4SJeremy Kemp                                { origin[0], origin[1], 0 },
8310*6fee86a4SJeremy Kemp                                { region[0], region[1], 1 }, row_pitch,
8311*6fee86a4SJeremy Kemp                                slice_pitch, events, event, err);
8312*6fee86a4SJeremy Kemp     }
8313*6fee86a4SJeremy Kemp 
8314*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 200
8315*6fee86a4SJeremy Kemp 
8316*6fee86a4SJeremy Kemp     /**
8317*6fee86a4SJeremy Kemp     * Enqueues a command that copies a region of memory from the source pointer to the destination pointer.
8318*6fee86a4SJeremy Kemp     * This function is specifically for transferring data between the host and a coarse-grained SVM buffer.
8319*6fee86a4SJeremy Kemp     */
8320*6fee86a4SJeremy Kemp     template<typename T>
enqueueMemcpySVM(T * dst_ptr,const T * src_ptr,cl_bool blocking,size_type size,const vector<Event> * events=nullptr,Event * event=nullptr) const8321*6fee86a4SJeremy Kemp     cl_int enqueueMemcpySVM(
8322*6fee86a4SJeremy Kemp             T *dst_ptr,
8323*6fee86a4SJeremy Kemp             const T *src_ptr,
8324*6fee86a4SJeremy Kemp             cl_bool blocking,
8325*6fee86a4SJeremy Kemp             size_type size,
8326*6fee86a4SJeremy Kemp             const vector<Event> *events = nullptr,
8327*6fee86a4SJeremy Kemp             Event *event = nullptr) const {
8328*6fee86a4SJeremy Kemp         cl_event tmp;
8329*6fee86a4SJeremy Kemp         cl_int err = detail::errHandler(::clEnqueueSVMMemcpy(
8330*6fee86a4SJeremy Kemp                 object_, blocking, static_cast<void *>(dst_ptr), static_cast<const void *>(src_ptr), size,
8331*6fee86a4SJeremy Kemp                 (events != nullptr) ? (cl_uint) events->size() : 0,
8332*6fee86a4SJeremy Kemp                 (events != nullptr && events->size() > 0) ? (cl_event *) &events->front() : nullptr,
8333*6fee86a4SJeremy Kemp                 (event != nullptr) ? &tmp : nullptr), __ENQUEUE_COPY_SVM_ERR);
8334*6fee86a4SJeremy Kemp 
8335*6fee86a4SJeremy Kemp         if (event != nullptr && err == CL_SUCCESS)
8336*6fee86a4SJeremy Kemp             *event = tmp;
8337*6fee86a4SJeremy Kemp 
8338*6fee86a4SJeremy Kemp         return err;
8339*6fee86a4SJeremy Kemp     }
8340*6fee86a4SJeremy Kemp 
8341*6fee86a4SJeremy Kemp     /**
8342*6fee86a4SJeremy Kemp     *Enqueues a command that will copy data from one coarse-grained SVM buffer to another.
8343*6fee86a4SJeremy Kemp     *This function takes two cl::pointer instances representing the destination and source buffers.
8344*6fee86a4SJeremy Kemp     */
8345*6fee86a4SJeremy Kemp     template<typename T, class D>
enqueueMemcpySVM(cl::pointer<T,D> & dst_ptr,const cl::pointer<T,D> & src_ptr,cl_bool blocking,size_type size,const vector<Event> * events=nullptr,Event * event=nullptr) const8346*6fee86a4SJeremy Kemp     cl_int enqueueMemcpySVM(
8347*6fee86a4SJeremy Kemp             cl::pointer<T, D> &dst_ptr,
8348*6fee86a4SJeremy Kemp             const cl::pointer<T, D> &src_ptr,
8349*6fee86a4SJeremy Kemp             cl_bool blocking,
8350*6fee86a4SJeremy Kemp             size_type size,
8351*6fee86a4SJeremy Kemp             const vector<Event> *events = nullptr,
8352*6fee86a4SJeremy Kemp             Event *event = nullptr) const {
8353*6fee86a4SJeremy Kemp         cl_event tmp;
8354*6fee86a4SJeremy Kemp         cl_int err = detail::errHandler(::clEnqueueSVMMemcpy(
8355*6fee86a4SJeremy Kemp                 object_, blocking, static_cast<void *>(dst_ptr.get()), static_cast<const void *>(src_ptr.get()),
8356*6fee86a4SJeremy Kemp                 size,
8357*6fee86a4SJeremy Kemp                 (events != nullptr) ? (cl_uint) events->size() : 0,
8358*6fee86a4SJeremy Kemp                 (events != nullptr && events->size() > 0) ? (cl_event *) &events->front() : nullptr,
8359*6fee86a4SJeremy Kemp                 (event != nullptr) ? &tmp : nullptr), __ENQUEUE_COPY_SVM_ERR);
8360*6fee86a4SJeremy Kemp 
8361*6fee86a4SJeremy Kemp         if (event != nullptr && err == CL_SUCCESS)
8362*6fee86a4SJeremy Kemp             *event = tmp;
8363*6fee86a4SJeremy Kemp 
8364*6fee86a4SJeremy Kemp         return err;
8365*6fee86a4SJeremy Kemp     }
8366*6fee86a4SJeremy Kemp 
8367*6fee86a4SJeremy Kemp     /**
8368*6fee86a4SJeremy Kemp     * Enqueues a command that will allow the host to update a region of a coarse-grained SVM buffer.
8369*6fee86a4SJeremy Kemp     * This variant takes a cl::vector instance.
8370*6fee86a4SJeremy Kemp     */
8371*6fee86a4SJeremy Kemp     template<typename T, class Alloc>
enqueueMemcpySVM(cl::vector<T,Alloc> & dst_container,const cl::vector<T,Alloc> & src_container,cl_bool blocking,const vector<Event> * events=nullptr,Event * event=nullptr) const8372*6fee86a4SJeremy Kemp     cl_int enqueueMemcpySVM(
8373*6fee86a4SJeremy Kemp             cl::vector<T, Alloc> &dst_container,
8374*6fee86a4SJeremy Kemp             const cl::vector<T, Alloc> &src_container,
8375*6fee86a4SJeremy Kemp             cl_bool blocking,
8376*6fee86a4SJeremy Kemp             const vector<Event> *events = nullptr,
8377*6fee86a4SJeremy Kemp             Event *event = nullptr) const {
8378*6fee86a4SJeremy Kemp         cl_event tmp;
8379*6fee86a4SJeremy Kemp         if(src_container.size() != dst_container.size()){
8380*6fee86a4SJeremy Kemp             return detail::errHandler(CL_INVALID_VALUE,__ENQUEUE_COPY_SVM_ERR);
8381*6fee86a4SJeremy Kemp         }
8382*6fee86a4SJeremy Kemp         cl_int err = detail::errHandler(::clEnqueueSVMMemcpy(
8383*6fee86a4SJeremy Kemp                 object_, blocking, static_cast<void *>(dst_container.data()),
8384*6fee86a4SJeremy Kemp                 static_cast<const void *>(src_container.data()),
8385*6fee86a4SJeremy Kemp                 dst_container.size() * sizeof(T),
8386*6fee86a4SJeremy Kemp                 (events != nullptr) ? (cl_uint) events->size() : 0,
8387*6fee86a4SJeremy Kemp                 (events != nullptr && events->size() > 0) ? (cl_event *) &events->front() : nullptr,
8388*6fee86a4SJeremy Kemp                 (event != NULL) ? &tmp : nullptr), __ENQUEUE_COPY_SVM_ERR);
8389*6fee86a4SJeremy Kemp 
8390*6fee86a4SJeremy Kemp         if (event != nullptr && err == CL_SUCCESS)
8391*6fee86a4SJeremy Kemp             *event = tmp;
8392*6fee86a4SJeremy Kemp 
8393*6fee86a4SJeremy Kemp         return err;
8394*6fee86a4SJeremy Kemp     }
8395*6fee86a4SJeremy Kemp 
8396*6fee86a4SJeremy Kemp     /**
8397*6fee86a4SJeremy Kemp     * Enqueues a command to fill a SVM buffer with a pattern.
8398*6fee86a4SJeremy Kemp     *
8399*6fee86a4SJeremy Kemp     */
8400*6fee86a4SJeremy Kemp     template<typename T, typename PatternType>
enqueueMemFillSVM(T * ptr,PatternType pattern,size_type size,const vector<Event> * events=nullptr,Event * event=nullptr) const8401*6fee86a4SJeremy Kemp     cl_int enqueueMemFillSVM(
8402*6fee86a4SJeremy Kemp             T *ptr,
8403*6fee86a4SJeremy Kemp             PatternType pattern,
8404*6fee86a4SJeremy Kemp             size_type size,
8405*6fee86a4SJeremy Kemp             const vector<Event> *events = nullptr,
8406*6fee86a4SJeremy Kemp             Event *event = nullptr) const {
8407*6fee86a4SJeremy Kemp         cl_event tmp;
8408*6fee86a4SJeremy Kemp         cl_int err = detail::errHandler(::clEnqueueSVMMemFill(
8409*6fee86a4SJeremy Kemp                 object_, static_cast<void *>(ptr), static_cast<void *>(&pattern),
8410*6fee86a4SJeremy Kemp                 sizeof(PatternType), size,
8411*6fee86a4SJeremy Kemp                 (events != nullptr) ? (cl_uint) events->size() : 0,
8412*6fee86a4SJeremy Kemp                 (events != nullptr && events->size() > 0) ? (cl_event *) &events->front() : nullptr,
8413*6fee86a4SJeremy Kemp                 (event != nullptr) ? &tmp : nullptr), __ENQUEUE_FILL_SVM_ERR);
8414*6fee86a4SJeremy Kemp 
8415*6fee86a4SJeremy Kemp         if (event != nullptr && err == CL_SUCCESS)
8416*6fee86a4SJeremy Kemp             *event = tmp;
8417*6fee86a4SJeremy Kemp 
8418*6fee86a4SJeremy Kemp         return err;
8419*6fee86a4SJeremy Kemp     }
8420*6fee86a4SJeremy Kemp 
8421*6fee86a4SJeremy Kemp     /**
8422*6fee86a4SJeremy Kemp     * Enqueues a command that fills a region of a coarse-grained SVM buffer with a specified pattern.
8423*6fee86a4SJeremy Kemp     * This variant takes a cl::pointer instance.
8424*6fee86a4SJeremy Kemp     */
8425*6fee86a4SJeremy Kemp     template<typename T, class D, typename PatternType>
enqueueMemFillSVM(cl::pointer<T,D> & ptr,PatternType pattern,size_type size,const vector<Event> * events=nullptr,Event * event=nullptr) const8426*6fee86a4SJeremy Kemp     cl_int enqueueMemFillSVM(
8427*6fee86a4SJeremy Kemp             cl::pointer<T, D> &ptr,
8428*6fee86a4SJeremy Kemp             PatternType pattern,
8429*6fee86a4SJeremy Kemp             size_type size,
8430*6fee86a4SJeremy Kemp             const vector<Event> *events = nullptr,
8431*6fee86a4SJeremy Kemp             Event *event = nullptr) const {
8432*6fee86a4SJeremy Kemp         cl_event tmp;
8433*6fee86a4SJeremy Kemp         cl_int err = detail::errHandler(::clEnqueueSVMMemFill(
8434*6fee86a4SJeremy Kemp                 object_, static_cast<void *>(ptr.get()), static_cast<void *>(&pattern),
8435*6fee86a4SJeremy Kemp                 sizeof(PatternType), size,
8436*6fee86a4SJeremy Kemp                 (events != nullptr) ? (cl_uint) events->size() : 0,
8437*6fee86a4SJeremy Kemp                 (events != nullptr && events->size() > 0) ? (cl_event *) &events->front() : nullptr,
8438*6fee86a4SJeremy Kemp                 (event != nullptr) ? &tmp : nullptr), __ENQUEUE_FILL_SVM_ERR);
8439*6fee86a4SJeremy Kemp 
8440*6fee86a4SJeremy Kemp         if (event != nullptr && err == CL_SUCCESS)
8441*6fee86a4SJeremy Kemp             *event = tmp;
8442*6fee86a4SJeremy Kemp 
8443*6fee86a4SJeremy Kemp         return err;
8444*6fee86a4SJeremy Kemp     }
8445*6fee86a4SJeremy Kemp 
8446*6fee86a4SJeremy Kemp     /**
8447*6fee86a4SJeremy Kemp     * Enqueues a command that will allow the host to fill a region of a coarse-grained SVM buffer with a specified pattern.
8448*6fee86a4SJeremy Kemp     * This variant takes a cl::vector instance.
8449*6fee86a4SJeremy Kemp     */
8450*6fee86a4SJeremy Kemp     template<typename T, class Alloc, typename PatternType>
enqueueMemFillSVM(cl::vector<T,Alloc> & container,PatternType pattern,const vector<Event> * events=nullptr,Event * event=nullptr) const8451*6fee86a4SJeremy Kemp     cl_int enqueueMemFillSVM(
8452*6fee86a4SJeremy Kemp             cl::vector<T, Alloc> &container,
8453*6fee86a4SJeremy Kemp             PatternType pattern,
8454*6fee86a4SJeremy Kemp             const vector<Event> *events = nullptr,
8455*6fee86a4SJeremy Kemp             Event* event = nullptr) const
8456*6fee86a4SJeremy Kemp     {
8457*6fee86a4SJeremy Kemp         cl_event tmp;
8458*6fee86a4SJeremy Kemp         cl_int err = detail::errHandler(::clEnqueueSVMMemFill(
8459*6fee86a4SJeremy Kemp                 object_, static_cast<void *>(container.data()), static_cast<void *>(&pattern),
8460*6fee86a4SJeremy Kemp                 sizeof(PatternType), container.size() * sizeof(T),
8461*6fee86a4SJeremy Kemp                 (events != nullptr) ? (cl_uint) events->size() : 0,
8462*6fee86a4SJeremy Kemp                 (events != nullptr && events->size() > 0) ? (cl_event *) &events->front() : nullptr,
8463*6fee86a4SJeremy Kemp                 (event != nullptr) ? &tmp : NULL), __ENQUEUE_FILL_SVM_ERR);
8464*6fee86a4SJeremy Kemp 
8465*6fee86a4SJeremy Kemp         if (event != nullptr && err == CL_SUCCESS)
8466*6fee86a4SJeremy Kemp             *event = tmp;
8467*6fee86a4SJeremy Kemp 
8468*6fee86a4SJeremy Kemp         return err;
8469*6fee86a4SJeremy Kemp     }
8470*6fee86a4SJeremy Kemp 
8471*6fee86a4SJeremy Kemp     /**
8472*6fee86a4SJeremy Kemp      * Enqueues a command that will allow the host to update a region of a coarse-grained SVM buffer.
8473*6fee86a4SJeremy Kemp      * This variant takes a raw SVM pointer.
8474*6fee86a4SJeremy Kemp      */
8475*6fee86a4SJeremy Kemp     template<typename T>
enqueueMapSVM(T * ptr,cl_bool blocking,cl_map_flags flags,size_type size,const vector<Event> * events=nullptr,Event * event=nullptr) const8476*6fee86a4SJeremy Kemp     cl_int enqueueMapSVM(
8477*6fee86a4SJeremy Kemp         T* ptr,
8478*6fee86a4SJeremy Kemp         cl_bool blocking,
8479*6fee86a4SJeremy Kemp         cl_map_flags flags,
8480*6fee86a4SJeremy Kemp         size_type size,
8481*6fee86a4SJeremy Kemp         const vector<Event>* events = nullptr,
8482*6fee86a4SJeremy Kemp         Event* event = nullptr) const
8483*6fee86a4SJeremy Kemp     {
8484*6fee86a4SJeremy Kemp         cl_event tmp;
8485*6fee86a4SJeremy Kemp         cl_int err = detail::errHandler(::clEnqueueSVMMap(
8486*6fee86a4SJeremy Kemp             object_, blocking, flags, static_cast<void*>(ptr), size,
8487*6fee86a4SJeremy Kemp             (events != nullptr) ? (cl_uint)events->size() : 0,
8488*6fee86a4SJeremy Kemp             (events != nullptr && events->size() > 0) ? (cl_event*)&events->front() : nullptr,
8489*6fee86a4SJeremy Kemp             (event != nullptr) ? &tmp : nullptr),
8490*6fee86a4SJeremy Kemp             __ENQUEUE_MAP_SVM_ERR);
8491*6fee86a4SJeremy Kemp 
8492*6fee86a4SJeremy Kemp         if (event != nullptr && err == CL_SUCCESS)
8493*6fee86a4SJeremy Kemp             *event = tmp;
8494*6fee86a4SJeremy Kemp 
8495*6fee86a4SJeremy Kemp         return err;
8496*6fee86a4SJeremy Kemp     }
8497*6fee86a4SJeremy Kemp 
8498*6fee86a4SJeremy Kemp 
8499*6fee86a4SJeremy Kemp     /**
8500*6fee86a4SJeremy Kemp      * Enqueues a command that will allow the host to update a region of a coarse-grained SVM buffer.
8501*6fee86a4SJeremy Kemp      * This variant takes a cl::pointer instance.
8502*6fee86a4SJeremy Kemp      */
8503*6fee86a4SJeremy Kemp     template<typename T, class D>
enqueueMapSVM(cl::pointer<T,D> & ptr,cl_bool blocking,cl_map_flags flags,size_type size,const vector<Event> * events=nullptr,Event * event=nullptr) const8504*6fee86a4SJeremy Kemp     cl_int enqueueMapSVM(
8505*6fee86a4SJeremy Kemp         cl::pointer<T, D> &ptr,
8506*6fee86a4SJeremy Kemp         cl_bool blocking,
8507*6fee86a4SJeremy Kemp         cl_map_flags flags,
8508*6fee86a4SJeremy Kemp         size_type size,
8509*6fee86a4SJeremy Kemp         const vector<Event>* events = nullptr,
8510*6fee86a4SJeremy Kemp         Event* event = nullptr) const
8511*6fee86a4SJeremy Kemp     {
8512*6fee86a4SJeremy Kemp         cl_event tmp;
8513*6fee86a4SJeremy Kemp         cl_int err = detail::errHandler(::clEnqueueSVMMap(
8514*6fee86a4SJeremy Kemp             object_, blocking, flags, static_cast<void*>(ptr.get()), size,
8515*6fee86a4SJeremy Kemp             (events != nullptr) ? (cl_uint)events->size() : 0,
8516*6fee86a4SJeremy Kemp             (events != nullptr && events->size() > 0) ? (cl_event*)&events->front() : nullptr,
8517*6fee86a4SJeremy Kemp             (event != nullptr) ? &tmp : nullptr),
8518*6fee86a4SJeremy Kemp             __ENQUEUE_MAP_SVM_ERR);
8519*6fee86a4SJeremy Kemp 
8520*6fee86a4SJeremy Kemp         if (event != nullptr && err == CL_SUCCESS)
8521*6fee86a4SJeremy Kemp             *event = tmp;
8522*6fee86a4SJeremy Kemp 
8523*6fee86a4SJeremy Kemp         return err;
8524*6fee86a4SJeremy Kemp     }
8525*6fee86a4SJeremy Kemp 
8526*6fee86a4SJeremy Kemp     /**
8527*6fee86a4SJeremy Kemp      * Enqueues a command that will allow the host to update a region of a coarse-grained SVM buffer.
8528*6fee86a4SJeremy Kemp      * This variant takes a cl::vector instance.
8529*6fee86a4SJeremy Kemp      */
8530*6fee86a4SJeremy Kemp     template<typename T, class Alloc>
enqueueMapSVM(cl::vector<T,Alloc> & container,cl_bool blocking,cl_map_flags flags,const vector<Event> * events=nullptr,Event * event=nullptr) const8531*6fee86a4SJeremy Kemp     cl_int enqueueMapSVM(
8532*6fee86a4SJeremy Kemp         cl::vector<T, Alloc> &container,
8533*6fee86a4SJeremy Kemp         cl_bool blocking,
8534*6fee86a4SJeremy Kemp         cl_map_flags flags,
8535*6fee86a4SJeremy Kemp         const vector<Event>* events = nullptr,
8536*6fee86a4SJeremy Kemp         Event* event = nullptr) const
8537*6fee86a4SJeremy Kemp     {
8538*6fee86a4SJeremy Kemp         cl_event tmp;
8539*6fee86a4SJeremy Kemp         cl_int err = detail::errHandler(::clEnqueueSVMMap(
8540*6fee86a4SJeremy Kemp             object_, blocking, flags, static_cast<void*>(container.data()), container.size()*sizeof(T),
8541*6fee86a4SJeremy Kemp             (events != nullptr) ? (cl_uint)events->size() : 0,
8542*6fee86a4SJeremy Kemp             (events != nullptr && events->size() > 0) ? (cl_event*)&events->front() : nullptr,
8543*6fee86a4SJeremy Kemp             (event != nullptr) ? &tmp : nullptr),
8544*6fee86a4SJeremy Kemp             __ENQUEUE_MAP_SVM_ERR);
8545*6fee86a4SJeremy Kemp 
8546*6fee86a4SJeremy Kemp         if (event != nullptr && err == CL_SUCCESS)
8547*6fee86a4SJeremy Kemp             *event = tmp;
8548*6fee86a4SJeremy Kemp 
8549*6fee86a4SJeremy Kemp         return err;
8550*6fee86a4SJeremy Kemp     }
8551*6fee86a4SJeremy Kemp #endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 200
8552*6fee86a4SJeremy Kemp 
enqueueUnmapMemObject(const Memory & memory,void * mapped_ptr,const vector<Event> * events=nullptr,Event * event=nullptr) const8553*6fee86a4SJeremy Kemp     cl_int enqueueUnmapMemObject(
8554*6fee86a4SJeremy Kemp         const Memory& memory,
8555*6fee86a4SJeremy Kemp         void* mapped_ptr,
8556*6fee86a4SJeremy Kemp         const vector<Event>* events = nullptr,
8557*6fee86a4SJeremy Kemp         Event* event = nullptr) const
8558*6fee86a4SJeremy Kemp     {
8559*6fee86a4SJeremy Kemp         cl_event tmp;
8560*6fee86a4SJeremy Kemp         cl_int err = detail::errHandler(
8561*6fee86a4SJeremy Kemp             ::clEnqueueUnmapMemObject(
8562*6fee86a4SJeremy Kemp                 object_, memory(), mapped_ptr,
8563*6fee86a4SJeremy Kemp                 (events != nullptr) ? (cl_uint) events->size() : 0,
8564*6fee86a4SJeremy Kemp                 (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
8565*6fee86a4SJeremy Kemp                 (event != nullptr) ? &tmp : nullptr),
8566*6fee86a4SJeremy Kemp             __ENQUEUE_UNMAP_MEM_OBJECT_ERR);
8567*6fee86a4SJeremy Kemp 
8568*6fee86a4SJeremy Kemp         if (event != nullptr && err == CL_SUCCESS)
8569*6fee86a4SJeremy Kemp             *event = tmp;
8570*6fee86a4SJeremy Kemp 
8571*6fee86a4SJeremy Kemp         return err;
8572*6fee86a4SJeremy Kemp     }
8573*6fee86a4SJeremy Kemp 
8574*6fee86a4SJeremy Kemp 
8575*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 200
8576*6fee86a4SJeremy Kemp     /**
8577*6fee86a4SJeremy Kemp      * Enqueues a command that will release a coarse-grained SVM buffer back to the OpenCL runtime.
8578*6fee86a4SJeremy Kemp      * This variant takes a raw SVM pointer.
8579*6fee86a4SJeremy Kemp      */
8580*6fee86a4SJeremy Kemp     template<typename T>
enqueueUnmapSVM(T * ptr,const vector<Event> * events=nullptr,Event * event=nullptr) const8581*6fee86a4SJeremy Kemp     cl_int enqueueUnmapSVM(
8582*6fee86a4SJeremy Kemp         T* ptr,
8583*6fee86a4SJeremy Kemp         const vector<Event>* events = nullptr,
8584*6fee86a4SJeremy Kemp         Event* event = nullptr) const
8585*6fee86a4SJeremy Kemp     {
8586*6fee86a4SJeremy Kemp         cl_event tmp;
8587*6fee86a4SJeremy Kemp         cl_int err = detail::errHandler(
8588*6fee86a4SJeremy Kemp             ::clEnqueueSVMUnmap(
8589*6fee86a4SJeremy Kemp             object_, static_cast<void*>(ptr),
8590*6fee86a4SJeremy Kemp             (events != nullptr) ? (cl_uint)events->size() : 0,
8591*6fee86a4SJeremy Kemp             (events != nullptr && events->size() > 0) ? (cl_event*)&events->front() : nullptr,
8592*6fee86a4SJeremy Kemp             (event != nullptr) ? &tmp : nullptr),
8593*6fee86a4SJeremy Kemp             __ENQUEUE_UNMAP_SVM_ERR);
8594*6fee86a4SJeremy Kemp 
8595*6fee86a4SJeremy Kemp         if (event != nullptr && err == CL_SUCCESS)
8596*6fee86a4SJeremy Kemp             *event = tmp;
8597*6fee86a4SJeremy Kemp 
8598*6fee86a4SJeremy Kemp         return err;
8599*6fee86a4SJeremy Kemp     }
8600*6fee86a4SJeremy Kemp 
8601*6fee86a4SJeremy Kemp     /**
8602*6fee86a4SJeremy Kemp      * Enqueues a command that will release a coarse-grained SVM buffer back to the OpenCL runtime.
8603*6fee86a4SJeremy Kemp      * This variant takes a cl::pointer instance.
8604*6fee86a4SJeremy Kemp      */
8605*6fee86a4SJeremy Kemp     template<typename T, class D>
enqueueUnmapSVM(cl::pointer<T,D> & ptr,const vector<Event> * events=nullptr,Event * event=nullptr) const8606*6fee86a4SJeremy Kemp     cl_int enqueueUnmapSVM(
8607*6fee86a4SJeremy Kemp         cl::pointer<T, D> &ptr,
8608*6fee86a4SJeremy Kemp         const vector<Event>* events = nullptr,
8609*6fee86a4SJeremy Kemp         Event* event = nullptr) const
8610*6fee86a4SJeremy Kemp     {
8611*6fee86a4SJeremy Kemp         cl_event tmp;
8612*6fee86a4SJeremy Kemp         cl_int err = detail::errHandler(
8613*6fee86a4SJeremy Kemp             ::clEnqueueSVMUnmap(
8614*6fee86a4SJeremy Kemp             object_, static_cast<void*>(ptr.get()),
8615*6fee86a4SJeremy Kemp             (events != nullptr) ? (cl_uint)events->size() : 0,
8616*6fee86a4SJeremy Kemp             (events != nullptr && events->size() > 0) ? (cl_event*)&events->front() : nullptr,
8617*6fee86a4SJeremy Kemp             (event != nullptr) ? &tmp : nullptr),
8618*6fee86a4SJeremy Kemp             __ENQUEUE_UNMAP_SVM_ERR);
8619*6fee86a4SJeremy Kemp 
8620*6fee86a4SJeremy Kemp         if (event != nullptr && err == CL_SUCCESS)
8621*6fee86a4SJeremy Kemp             *event = tmp;
8622*6fee86a4SJeremy Kemp 
8623*6fee86a4SJeremy Kemp         return err;
8624*6fee86a4SJeremy Kemp     }
8625*6fee86a4SJeremy Kemp 
8626*6fee86a4SJeremy Kemp     /**
8627*6fee86a4SJeremy Kemp      * Enqueues a command that will release a coarse-grained SVM buffer back to the OpenCL runtime.
8628*6fee86a4SJeremy Kemp      * This variant takes a cl::vector instance.
8629*6fee86a4SJeremy Kemp      */
8630*6fee86a4SJeremy Kemp     template<typename T, class Alloc>
enqueueUnmapSVM(cl::vector<T,Alloc> & container,const vector<Event> * events=nullptr,Event * event=nullptr) const8631*6fee86a4SJeremy Kemp     cl_int enqueueUnmapSVM(
8632*6fee86a4SJeremy Kemp         cl::vector<T, Alloc> &container,
8633*6fee86a4SJeremy Kemp         const vector<Event>* events = nullptr,
8634*6fee86a4SJeremy Kemp         Event* event = nullptr) const
8635*6fee86a4SJeremy Kemp     {
8636*6fee86a4SJeremy Kemp         cl_event tmp;
8637*6fee86a4SJeremy Kemp         cl_int err = detail::errHandler(
8638*6fee86a4SJeremy Kemp             ::clEnqueueSVMUnmap(
8639*6fee86a4SJeremy Kemp             object_, static_cast<void*>(container.data()),
8640*6fee86a4SJeremy Kemp             (events != nullptr) ? (cl_uint)events->size() : 0,
8641*6fee86a4SJeremy Kemp             (events != nullptr && events->size() > 0) ? (cl_event*)&events->front() : nullptr,
8642*6fee86a4SJeremy Kemp             (event != nullptr) ? &tmp : nullptr),
8643*6fee86a4SJeremy Kemp             __ENQUEUE_UNMAP_SVM_ERR);
8644*6fee86a4SJeremy Kemp 
8645*6fee86a4SJeremy Kemp         if (event != nullptr && err == CL_SUCCESS)
8646*6fee86a4SJeremy Kemp             *event = tmp;
8647*6fee86a4SJeremy Kemp 
8648*6fee86a4SJeremy Kemp         return err;
8649*6fee86a4SJeremy Kemp     }
8650*6fee86a4SJeremy Kemp #endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 200
8651*6fee86a4SJeremy Kemp 
8652*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 120
8653*6fee86a4SJeremy Kemp     /**
8654*6fee86a4SJeremy Kemp      * Enqueues a marker command which waits for either a list of events to complete,
8655*6fee86a4SJeremy Kemp      * or all previously enqueued commands to complete.
8656*6fee86a4SJeremy Kemp      *
8657*6fee86a4SJeremy Kemp      * Enqueues a marker command which waits for either a list of events to complete,
8658*6fee86a4SJeremy Kemp      * or if the list is empty it waits for all commands previously enqueued in command_queue
8659*6fee86a4SJeremy Kemp      * to complete before it completes. This command returns an event which can be waited on,
8660*6fee86a4SJeremy Kemp      * i.e. this event can be waited on to insure that all events either in the event_wait_list
8661*6fee86a4SJeremy Kemp      * or all previously enqueued commands, queued before this command to command_queue,
8662*6fee86a4SJeremy Kemp      * have completed.
8663*6fee86a4SJeremy Kemp      */
enqueueMarkerWithWaitList(const vector<Event> * events=nullptr,Event * event=nullptr) const8664*6fee86a4SJeremy Kemp     cl_int enqueueMarkerWithWaitList(
8665*6fee86a4SJeremy Kemp         const vector<Event> *events = nullptr,
8666*6fee86a4SJeremy Kemp         Event *event = nullptr) const
8667*6fee86a4SJeremy Kemp     {
8668*6fee86a4SJeremy Kemp         cl_event tmp;
8669*6fee86a4SJeremy Kemp         cl_int err = detail::errHandler(
8670*6fee86a4SJeremy Kemp             ::clEnqueueMarkerWithWaitList(
8671*6fee86a4SJeremy Kemp                 object_,
8672*6fee86a4SJeremy Kemp                 (events != nullptr) ? (cl_uint) events->size() : 0,
8673*6fee86a4SJeremy Kemp                 (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
8674*6fee86a4SJeremy Kemp                 (event != nullptr) ? &tmp : nullptr),
8675*6fee86a4SJeremy Kemp             __ENQUEUE_MARKER_WAIT_LIST_ERR);
8676*6fee86a4SJeremy Kemp 
8677*6fee86a4SJeremy Kemp         if (event != nullptr && err == CL_SUCCESS)
8678*6fee86a4SJeremy Kemp             *event = tmp;
8679*6fee86a4SJeremy Kemp 
8680*6fee86a4SJeremy Kemp         return err;
8681*6fee86a4SJeremy Kemp     }
8682*6fee86a4SJeremy Kemp 
8683*6fee86a4SJeremy Kemp     /**
8684*6fee86a4SJeremy Kemp      * A synchronization point that enqueues a barrier operation.
8685*6fee86a4SJeremy Kemp      *
8686*6fee86a4SJeremy Kemp      * Enqueues a barrier command which waits for either a list of events to complete,
8687*6fee86a4SJeremy Kemp      * or if the list is empty it waits for all commands previously enqueued in command_queue
8688*6fee86a4SJeremy Kemp      * to complete before it completes. This command blocks command execution, that is, any
8689*6fee86a4SJeremy Kemp      * following commands enqueued after it do not execute until it completes. This command
8690*6fee86a4SJeremy Kemp      * returns an event which can be waited on, i.e. this event can be waited on to insure that
8691*6fee86a4SJeremy Kemp      * all events either in the event_wait_list or all previously enqueued commands, queued
8692*6fee86a4SJeremy Kemp      * before this command to command_queue, have completed.
8693*6fee86a4SJeremy Kemp      */
enqueueBarrierWithWaitList(const vector<Event> * events=nullptr,Event * event=nullptr) const8694*6fee86a4SJeremy Kemp     cl_int enqueueBarrierWithWaitList(
8695*6fee86a4SJeremy Kemp         const vector<Event> *events = nullptr,
8696*6fee86a4SJeremy Kemp         Event *event = nullptr) const
8697*6fee86a4SJeremy Kemp     {
8698*6fee86a4SJeremy Kemp         cl_event tmp;
8699*6fee86a4SJeremy Kemp         cl_int err = detail::errHandler(
8700*6fee86a4SJeremy Kemp             ::clEnqueueBarrierWithWaitList(
8701*6fee86a4SJeremy Kemp                 object_,
8702*6fee86a4SJeremy Kemp                 (events != nullptr) ? (cl_uint) events->size() : 0,
8703*6fee86a4SJeremy Kemp                 (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
8704*6fee86a4SJeremy Kemp                 (event != nullptr) ? &tmp : nullptr),
8705*6fee86a4SJeremy Kemp             __ENQUEUE_BARRIER_WAIT_LIST_ERR);
8706*6fee86a4SJeremy Kemp 
8707*6fee86a4SJeremy Kemp         if (event != nullptr && err == CL_SUCCESS)
8708*6fee86a4SJeremy Kemp             *event = tmp;
8709*6fee86a4SJeremy Kemp 
8710*6fee86a4SJeremy Kemp         return err;
8711*6fee86a4SJeremy Kemp     }
8712*6fee86a4SJeremy Kemp 
8713*6fee86a4SJeremy Kemp     /**
8714*6fee86a4SJeremy Kemp      * Enqueues a command to indicate with which device a set of memory objects
8715*6fee86a4SJeremy Kemp      * should be associated.
8716*6fee86a4SJeremy Kemp      */
enqueueMigrateMemObjects(const vector<Memory> & memObjects,cl_mem_migration_flags flags,const vector<Event> * events=nullptr,Event * event=nullptr) const8717*6fee86a4SJeremy Kemp     cl_int enqueueMigrateMemObjects(
8718*6fee86a4SJeremy Kemp         const vector<Memory> &memObjects,
8719*6fee86a4SJeremy Kemp         cl_mem_migration_flags flags,
8720*6fee86a4SJeremy Kemp         const vector<Event>* events = nullptr,
8721*6fee86a4SJeremy Kemp         Event* event = nullptr
8722*6fee86a4SJeremy Kemp         ) const
8723*6fee86a4SJeremy Kemp     {
8724*6fee86a4SJeremy Kemp         cl_event tmp;
8725*6fee86a4SJeremy Kemp 
8726*6fee86a4SJeremy Kemp         vector<cl_mem> localMemObjects(memObjects.size());
8727*6fee86a4SJeremy Kemp 
8728*6fee86a4SJeremy Kemp         for( int i = 0; i < (int)memObjects.size(); ++i ) {
8729*6fee86a4SJeremy Kemp             localMemObjects[i] = memObjects[i]();
8730*6fee86a4SJeremy Kemp         }
8731*6fee86a4SJeremy Kemp 
8732*6fee86a4SJeremy Kemp         cl_int err = detail::errHandler(
8733*6fee86a4SJeremy Kemp             ::clEnqueueMigrateMemObjects(
8734*6fee86a4SJeremy Kemp                 object_,
8735*6fee86a4SJeremy Kemp                 (cl_uint)memObjects.size(),
8736*6fee86a4SJeremy Kemp                 localMemObjects.data(),
8737*6fee86a4SJeremy Kemp                 flags,
8738*6fee86a4SJeremy Kemp                 (events != nullptr) ? (cl_uint) events->size() : 0,
8739*6fee86a4SJeremy Kemp                 (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
8740*6fee86a4SJeremy Kemp                 (event != nullptr) ? &tmp : nullptr),
8741*6fee86a4SJeremy Kemp             __ENQUEUE_UNMAP_MEM_OBJECT_ERR);
8742*6fee86a4SJeremy Kemp 
8743*6fee86a4SJeremy Kemp         if (event != nullptr && err == CL_SUCCESS)
8744*6fee86a4SJeremy Kemp             *event = tmp;
8745*6fee86a4SJeremy Kemp 
8746*6fee86a4SJeremy Kemp         return err;
8747*6fee86a4SJeremy Kemp     }
8748*6fee86a4SJeremy Kemp #endif // CL_HPP_TARGET_OPENCL_VERSION >= 120
8749*6fee86a4SJeremy Kemp 
8750*6fee86a4SJeremy Kemp 
8751*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 210
8752*6fee86a4SJeremy Kemp     /**
8753*6fee86a4SJeremy Kemp      * Enqueues a command that will allow the host associate ranges within a set of
8754*6fee86a4SJeremy Kemp      * SVM allocations with a device.
8755*6fee86a4SJeremy Kemp      * @param sizes - The length from each pointer to migrate.
8756*6fee86a4SJeremy Kemp      */
8757*6fee86a4SJeremy Kemp     template<typename T>
enqueueMigrateSVM(const cl::vector<T * > & svmRawPointers,const cl::vector<size_type> & sizes,cl_mem_migration_flags flags=0,const vector<Event> * events=nullptr,Event * event=nullptr) const8758*6fee86a4SJeremy Kemp     cl_int enqueueMigrateSVM(
8759*6fee86a4SJeremy Kemp         const cl::vector<T*> &svmRawPointers,
8760*6fee86a4SJeremy Kemp         const cl::vector<size_type> &sizes,
8761*6fee86a4SJeremy Kemp         cl_mem_migration_flags flags = 0,
8762*6fee86a4SJeremy Kemp         const vector<Event>* events = nullptr,
8763*6fee86a4SJeremy Kemp         Event* event = nullptr) const
8764*6fee86a4SJeremy Kemp     {
8765*6fee86a4SJeremy Kemp         cl_event tmp;
8766*6fee86a4SJeremy Kemp         cl_int err = detail::errHandler(::clEnqueueSVMMigrateMem(
8767*6fee86a4SJeremy Kemp             object_,
8768*6fee86a4SJeremy Kemp             svmRawPointers.size(), static_cast<void**>(svmRawPointers.data()),
8769*6fee86a4SJeremy Kemp             sizes.data(), // array of sizes not passed
8770*6fee86a4SJeremy Kemp             flags,
8771*6fee86a4SJeremy Kemp             (events != nullptr) ? (cl_uint)events->size() : 0,
8772*6fee86a4SJeremy Kemp             (events != nullptr && events->size() > 0) ? (cl_event*)&events->front() : nullptr,
8773*6fee86a4SJeremy Kemp             (event != nullptr) ? &tmp : nullptr),
8774*6fee86a4SJeremy Kemp             __ENQUEUE_MIGRATE_SVM_ERR);
8775*6fee86a4SJeremy Kemp 
8776*6fee86a4SJeremy Kemp         if (event != nullptr && err == CL_SUCCESS)
8777*6fee86a4SJeremy Kemp             *event = tmp;
8778*6fee86a4SJeremy Kemp 
8779*6fee86a4SJeremy Kemp         return err;
8780*6fee86a4SJeremy Kemp     }
8781*6fee86a4SJeremy Kemp 
8782*6fee86a4SJeremy Kemp     /**
8783*6fee86a4SJeremy Kemp      * Enqueues a command that will allow the host associate a set of SVM allocations with
8784*6fee86a4SJeremy Kemp      * a device.
8785*6fee86a4SJeremy Kemp      */
8786*6fee86a4SJeremy Kemp     template<typename T>
enqueueMigrateSVM(const cl::vector<T * > & svmRawPointers,cl_mem_migration_flags flags=0,const vector<Event> * events=nullptr,Event * event=nullptr) const8787*6fee86a4SJeremy Kemp     cl_int enqueueMigrateSVM(
8788*6fee86a4SJeremy Kemp         const cl::vector<T*> &svmRawPointers,
8789*6fee86a4SJeremy Kemp         cl_mem_migration_flags flags = 0,
8790*6fee86a4SJeremy Kemp         const vector<Event>* events = nullptr,
8791*6fee86a4SJeremy Kemp         Event* event = nullptr) const
8792*6fee86a4SJeremy Kemp     {
8793*6fee86a4SJeremy Kemp         return enqueueMigrateSVM(svmRawPointers, cl::vector<size_type>(svmRawPointers.size()), flags, events, event);
8794*6fee86a4SJeremy Kemp     }
8795*6fee86a4SJeremy Kemp 
8796*6fee86a4SJeremy Kemp 
8797*6fee86a4SJeremy Kemp     /**
8798*6fee86a4SJeremy Kemp      * Enqueues a command that will allow the host associate ranges within a set of
8799*6fee86a4SJeremy Kemp      * SVM allocations with a device.
8800*6fee86a4SJeremy Kemp      * @param sizes - The length from each pointer to migrate.
8801*6fee86a4SJeremy Kemp      */
8802*6fee86a4SJeremy Kemp     template<typename T, class D>
enqueueMigrateSVM(const cl::vector<cl::pointer<T,D>> & svmPointers,const cl::vector<size_type> & sizes,cl_mem_migration_flags flags=0,const vector<Event> * events=nullptr,Event * event=nullptr) const8803*6fee86a4SJeremy Kemp     cl_int enqueueMigrateSVM(
8804*6fee86a4SJeremy Kemp         const cl::vector<cl::pointer<T, D>> &svmPointers,
8805*6fee86a4SJeremy Kemp         const cl::vector<size_type> &sizes,
8806*6fee86a4SJeremy Kemp         cl_mem_migration_flags flags = 0,
8807*6fee86a4SJeremy Kemp         const vector<Event>* events = nullptr,
8808*6fee86a4SJeremy Kemp         Event* event = nullptr) const
8809*6fee86a4SJeremy Kemp     {
8810*6fee86a4SJeremy Kemp         cl::vector<void*> svmRawPointers;
8811*6fee86a4SJeremy Kemp         svmRawPointers.reserve(svmPointers.size());
8812*6fee86a4SJeremy Kemp         for (auto p : svmPointers) {
8813*6fee86a4SJeremy Kemp             svmRawPointers.push_back(static_cast<void*>(p.get()));
8814*6fee86a4SJeremy Kemp         }
8815*6fee86a4SJeremy Kemp 
8816*6fee86a4SJeremy Kemp         return enqueueMigrateSVM(svmRawPointers, sizes, flags, events, event);
8817*6fee86a4SJeremy Kemp     }
8818*6fee86a4SJeremy Kemp 
8819*6fee86a4SJeremy Kemp 
8820*6fee86a4SJeremy Kemp     /**
8821*6fee86a4SJeremy Kemp      * Enqueues a command that will allow the host associate a set of SVM allocations with
8822*6fee86a4SJeremy Kemp      * a device.
8823*6fee86a4SJeremy Kemp      */
8824*6fee86a4SJeremy Kemp     template<typename T, class D>
enqueueMigrateSVM(const cl::vector<cl::pointer<T,D>> & svmPointers,cl_mem_migration_flags flags=0,const vector<Event> * events=nullptr,Event * event=nullptr) const8825*6fee86a4SJeremy Kemp     cl_int enqueueMigrateSVM(
8826*6fee86a4SJeremy Kemp         const cl::vector<cl::pointer<T, D>> &svmPointers,
8827*6fee86a4SJeremy Kemp         cl_mem_migration_flags flags = 0,
8828*6fee86a4SJeremy Kemp         const vector<Event>* events = nullptr,
8829*6fee86a4SJeremy Kemp         Event* event = nullptr) const
8830*6fee86a4SJeremy Kemp     {
8831*6fee86a4SJeremy Kemp         return enqueueMigrateSVM(svmPointers, cl::vector<size_type>(svmPointers.size()), flags, events, event);
8832*6fee86a4SJeremy Kemp     }
8833*6fee86a4SJeremy Kemp 
8834*6fee86a4SJeremy Kemp     /**
8835*6fee86a4SJeremy Kemp      * Enqueues a command that will allow the host associate ranges within a set of
8836*6fee86a4SJeremy Kemp      * SVM allocations with a device.
8837*6fee86a4SJeremy Kemp      * @param sizes - The length from the beginning of each container to migrate.
8838*6fee86a4SJeremy Kemp      */
8839*6fee86a4SJeremy Kemp     template<typename T, class Alloc>
enqueueMigrateSVM(const cl::vector<cl::vector<T,Alloc>> & svmContainers,const cl::vector<size_type> & sizes,cl_mem_migration_flags flags=0,const vector<Event> * events=nullptr,Event * event=nullptr) const8840*6fee86a4SJeremy Kemp     cl_int enqueueMigrateSVM(
8841*6fee86a4SJeremy Kemp         const cl::vector<cl::vector<T, Alloc>> &svmContainers,
8842*6fee86a4SJeremy Kemp         const cl::vector<size_type> &sizes,
8843*6fee86a4SJeremy Kemp         cl_mem_migration_flags flags = 0,
8844*6fee86a4SJeremy Kemp         const vector<Event>* events = nullptr,
8845*6fee86a4SJeremy Kemp         Event* event = nullptr) const
8846*6fee86a4SJeremy Kemp     {
8847*6fee86a4SJeremy Kemp         cl::vector<void*> svmRawPointers;
8848*6fee86a4SJeremy Kemp         svmRawPointers.reserve(svmContainers.size());
8849*6fee86a4SJeremy Kemp         for (auto p : svmContainers) {
8850*6fee86a4SJeremy Kemp             svmRawPointers.push_back(static_cast<void*>(p.data()));
8851*6fee86a4SJeremy Kemp         }
8852*6fee86a4SJeremy Kemp 
8853*6fee86a4SJeremy Kemp         return enqueueMigrateSVM(svmRawPointers, sizes, flags, events, event);
8854*6fee86a4SJeremy Kemp     }
8855*6fee86a4SJeremy Kemp 
8856*6fee86a4SJeremy Kemp     /**
8857*6fee86a4SJeremy Kemp      * Enqueues a command that will allow the host associate a set of SVM allocations with
8858*6fee86a4SJeremy Kemp      * a device.
8859*6fee86a4SJeremy Kemp      */
8860*6fee86a4SJeremy Kemp     template<typename T, class Alloc>
enqueueMigrateSVM(const cl::vector<cl::vector<T,Alloc>> & svmContainers,cl_mem_migration_flags flags=0,const vector<Event> * events=nullptr,Event * event=nullptr) const8861*6fee86a4SJeremy Kemp     cl_int enqueueMigrateSVM(
8862*6fee86a4SJeremy Kemp         const cl::vector<cl::vector<T, Alloc>> &svmContainers,
8863*6fee86a4SJeremy Kemp         cl_mem_migration_flags flags = 0,
8864*6fee86a4SJeremy Kemp         const vector<Event>* events = nullptr,
8865*6fee86a4SJeremy Kemp         Event* event = nullptr) const
8866*6fee86a4SJeremy Kemp     {
8867*6fee86a4SJeremy Kemp         return enqueueMigrateSVM(svmContainers, cl::vector<size_type>(svmContainers.size()), flags, events, event);
8868*6fee86a4SJeremy Kemp     }
8869*6fee86a4SJeremy Kemp 
8870*6fee86a4SJeremy Kemp #endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 210
8871*6fee86a4SJeremy Kemp 
enqueueNDRangeKernel(const Kernel & kernel,const NDRange & offset,const NDRange & global,const NDRange & local=NullRange,const vector<Event> * events=nullptr,Event * event=nullptr) const8872*6fee86a4SJeremy Kemp     cl_int enqueueNDRangeKernel(
8873*6fee86a4SJeremy Kemp         const Kernel& kernel,
8874*6fee86a4SJeremy Kemp         const NDRange& offset,
8875*6fee86a4SJeremy Kemp         const NDRange& global,
8876*6fee86a4SJeremy Kemp         const NDRange& local = NullRange,
8877*6fee86a4SJeremy Kemp         const vector<Event>* events = nullptr,
8878*6fee86a4SJeremy Kemp         Event* event = nullptr) const
8879*6fee86a4SJeremy Kemp     {
8880*6fee86a4SJeremy Kemp         cl_event tmp;
8881*6fee86a4SJeremy Kemp         cl_int err = detail::errHandler(
8882*6fee86a4SJeremy Kemp             ::clEnqueueNDRangeKernel(
8883*6fee86a4SJeremy Kemp                 object_, kernel(), (cl_uint) global.dimensions(),
8884*6fee86a4SJeremy Kemp                 offset.dimensions() != 0 ? (const size_type*) offset : nullptr,
8885*6fee86a4SJeremy Kemp                 (const size_type*) global,
8886*6fee86a4SJeremy Kemp                 local.dimensions() != 0 ? (const size_type*) local : nullptr,
8887*6fee86a4SJeremy Kemp                 (events != nullptr) ? (cl_uint) events->size() : 0,
8888*6fee86a4SJeremy Kemp                 (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
8889*6fee86a4SJeremy Kemp                 (event != nullptr) ? &tmp : nullptr),
8890*6fee86a4SJeremy Kemp             __ENQUEUE_NDRANGE_KERNEL_ERR);
8891*6fee86a4SJeremy Kemp 
8892*6fee86a4SJeremy Kemp         if (event != nullptr && err == CL_SUCCESS)
8893*6fee86a4SJeremy Kemp             *event = tmp;
8894*6fee86a4SJeremy Kemp 
8895*6fee86a4SJeremy Kemp         return err;
8896*6fee86a4SJeremy Kemp     }
8897*6fee86a4SJeremy Kemp 
8898*6fee86a4SJeremy Kemp #if defined(CL_USE_DEPRECATED_OPENCL_1_2_APIS)
enqueueTask(const Kernel & kernel,const vector<Event> * events=nullptr,Event * event=nullptr) const8899*6fee86a4SJeremy Kemp     CL_API_PREFIX__VERSION_1_2_DEPRECATED cl_int enqueueTask(
8900*6fee86a4SJeremy Kemp         const Kernel& kernel,
8901*6fee86a4SJeremy Kemp         const vector<Event>* events = nullptr,
8902*6fee86a4SJeremy Kemp         Event* event = nullptr) const CL_API_SUFFIX__VERSION_1_2_DEPRECATED
8903*6fee86a4SJeremy Kemp     {
8904*6fee86a4SJeremy Kemp         cl_event tmp;
8905*6fee86a4SJeremy Kemp         cl_int err = detail::errHandler(
8906*6fee86a4SJeremy Kemp             ::clEnqueueTask(
8907*6fee86a4SJeremy Kemp                 object_, kernel(),
8908*6fee86a4SJeremy Kemp                 (events != nullptr) ? (cl_uint) events->size() : 0,
8909*6fee86a4SJeremy Kemp                 (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
8910*6fee86a4SJeremy Kemp                 (event != nullptr) ? &tmp : nullptr),
8911*6fee86a4SJeremy Kemp             __ENQUEUE_TASK_ERR);
8912*6fee86a4SJeremy Kemp 
8913*6fee86a4SJeremy Kemp         if (event != nullptr && err == CL_SUCCESS)
8914*6fee86a4SJeremy Kemp             *event = tmp;
8915*6fee86a4SJeremy Kemp 
8916*6fee86a4SJeremy Kemp         return err;
8917*6fee86a4SJeremy Kemp     }
8918*6fee86a4SJeremy Kemp #endif // #if defined(CL_USE_DEPRECATED_OPENCL_1_2_APIS)
8919*6fee86a4SJeremy Kemp 
enqueueNativeKernel(void (CL_CALLBACK * userFptr)(void *),std::pair<void *,size_type> args,const vector<Memory> * mem_objects=nullptr,const vector<const void * > * mem_locs=nullptr,const vector<Event> * events=nullptr,Event * event=nullptr) const8920*6fee86a4SJeremy Kemp     cl_int enqueueNativeKernel(
8921*6fee86a4SJeremy Kemp         void (CL_CALLBACK *userFptr)(void *),
8922*6fee86a4SJeremy Kemp         std::pair<void*, size_type> args,
8923*6fee86a4SJeremy Kemp         const vector<Memory>* mem_objects = nullptr,
8924*6fee86a4SJeremy Kemp         const vector<const void*>* mem_locs = nullptr,
8925*6fee86a4SJeremy Kemp         const vector<Event>* events = nullptr,
8926*6fee86a4SJeremy Kemp         Event* event = nullptr) const
8927*6fee86a4SJeremy Kemp     {
8928*6fee86a4SJeremy Kemp         cl_event tmp;
8929*6fee86a4SJeremy Kemp         cl_int err = detail::errHandler(
8930*6fee86a4SJeremy Kemp             ::clEnqueueNativeKernel(
8931*6fee86a4SJeremy Kemp                 object_, userFptr, args.first, args.second,
8932*6fee86a4SJeremy Kemp                 (mem_objects != nullptr) ? (cl_uint) mem_objects->size() : 0,
8933*6fee86a4SJeremy Kemp                 (mem_objects->size() > 0 ) ? reinterpret_cast<const cl_mem *>(mem_objects->data()) : nullptr,
8934*6fee86a4SJeremy Kemp                 (mem_locs != nullptr && mem_locs->size() > 0) ? (const void **) &mem_locs->front() : nullptr,
8935*6fee86a4SJeremy Kemp                 (events != nullptr) ? (cl_uint) events->size() : 0,
8936*6fee86a4SJeremy Kemp                 (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
8937*6fee86a4SJeremy Kemp                 (event != nullptr) ? &tmp : nullptr),
8938*6fee86a4SJeremy Kemp             __ENQUEUE_NATIVE_KERNEL);
8939*6fee86a4SJeremy Kemp 
8940*6fee86a4SJeremy Kemp         if (event != nullptr && err == CL_SUCCESS)
8941*6fee86a4SJeremy Kemp             *event = tmp;
8942*6fee86a4SJeremy Kemp 
8943*6fee86a4SJeremy Kemp         return err;
8944*6fee86a4SJeremy Kemp     }
8945*6fee86a4SJeremy Kemp 
8946*6fee86a4SJeremy Kemp /**
8947*6fee86a4SJeremy Kemp  * Deprecated APIs for 1.2
8948*6fee86a4SJeremy Kemp  */
8949*6fee86a4SJeremy Kemp #if defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS)
8950*6fee86a4SJeremy Kemp     CL_API_PREFIX__VERSION_1_1_DEPRECATED
enqueueMarker(Event * event=nullptr) const8951*6fee86a4SJeremy Kemp     cl_int enqueueMarker(Event* event = nullptr) const CL_API_SUFFIX__VERSION_1_1_DEPRECATED
8952*6fee86a4SJeremy Kemp     {
8953*6fee86a4SJeremy Kemp         cl_event tmp;
8954*6fee86a4SJeremy Kemp         cl_int err = detail::errHandler(
8955*6fee86a4SJeremy Kemp             ::clEnqueueMarker(
8956*6fee86a4SJeremy Kemp                 object_,
8957*6fee86a4SJeremy Kemp                 (event != nullptr) ? &tmp : nullptr),
8958*6fee86a4SJeremy Kemp             __ENQUEUE_MARKER_ERR);
8959*6fee86a4SJeremy Kemp 
8960*6fee86a4SJeremy Kemp         if (event != nullptr && err == CL_SUCCESS)
8961*6fee86a4SJeremy Kemp             *event = tmp;
8962*6fee86a4SJeremy Kemp 
8963*6fee86a4SJeremy Kemp         return err;
8964*6fee86a4SJeremy Kemp     }
8965*6fee86a4SJeremy Kemp 
8966*6fee86a4SJeremy Kemp     CL_API_PREFIX__VERSION_1_1_DEPRECATED
enqueueWaitForEvents(const vector<Event> & events) const8967*6fee86a4SJeremy Kemp     cl_int enqueueWaitForEvents(const vector<Event>& events) const CL_API_SUFFIX__VERSION_1_1_DEPRECATED
8968*6fee86a4SJeremy Kemp     {
8969*6fee86a4SJeremy Kemp         return detail::errHandler(
8970*6fee86a4SJeremy Kemp             ::clEnqueueWaitForEvents(
8971*6fee86a4SJeremy Kemp                 object_,
8972*6fee86a4SJeremy Kemp                 (cl_uint) events.size(),
8973*6fee86a4SJeremy Kemp                 events.size() > 0 ? (const cl_event*) &events.front() : nullptr),
8974*6fee86a4SJeremy Kemp             __ENQUEUE_WAIT_FOR_EVENTS_ERR);
8975*6fee86a4SJeremy Kemp     }
8976*6fee86a4SJeremy Kemp #endif // defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS)
8977*6fee86a4SJeremy Kemp 
enqueueAcquireGLObjects(const vector<Memory> * mem_objects=nullptr,const vector<Event> * events=nullptr,Event * event=nullptr) const8978*6fee86a4SJeremy Kemp     cl_int enqueueAcquireGLObjects(
8979*6fee86a4SJeremy Kemp          const vector<Memory>* mem_objects = nullptr,
8980*6fee86a4SJeremy Kemp          const vector<Event>* events = nullptr,
8981*6fee86a4SJeremy Kemp          Event* event = nullptr) const
8982*6fee86a4SJeremy Kemp      {
8983*6fee86a4SJeremy Kemp         cl_event tmp;
8984*6fee86a4SJeremy Kemp         cl_int err = detail::errHandler(
8985*6fee86a4SJeremy Kemp              ::clEnqueueAcquireGLObjects(
8986*6fee86a4SJeremy Kemp                  object_,
8987*6fee86a4SJeremy Kemp                  (mem_objects != nullptr) ? (cl_uint) mem_objects->size() : 0,
8988*6fee86a4SJeremy Kemp                  (mem_objects != nullptr && mem_objects->size() > 0) ? (const cl_mem *) &mem_objects->front(): nullptr,
8989*6fee86a4SJeremy Kemp                  (events != nullptr) ? (cl_uint) events->size() : 0,
8990*6fee86a4SJeremy Kemp                  (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
8991*6fee86a4SJeremy Kemp                  (event != nullptr) ? &tmp : nullptr),
8992*6fee86a4SJeremy Kemp              __ENQUEUE_ACQUIRE_GL_ERR);
8993*6fee86a4SJeremy Kemp 
8994*6fee86a4SJeremy Kemp         if (event != nullptr && err == CL_SUCCESS)
8995*6fee86a4SJeremy Kemp             *event = tmp;
8996*6fee86a4SJeremy Kemp 
8997*6fee86a4SJeremy Kemp         return err;
8998*6fee86a4SJeremy Kemp      }
8999*6fee86a4SJeremy Kemp 
enqueueReleaseGLObjects(const vector<Memory> * mem_objects=nullptr,const vector<Event> * events=nullptr,Event * event=nullptr) const9000*6fee86a4SJeremy Kemp     cl_int enqueueReleaseGLObjects(
9001*6fee86a4SJeremy Kemp          const vector<Memory>* mem_objects = nullptr,
9002*6fee86a4SJeremy Kemp          const vector<Event>* events = nullptr,
9003*6fee86a4SJeremy Kemp          Event* event = nullptr) const
9004*6fee86a4SJeremy Kemp      {
9005*6fee86a4SJeremy Kemp         cl_event tmp;
9006*6fee86a4SJeremy Kemp         cl_int err = detail::errHandler(
9007*6fee86a4SJeremy Kemp              ::clEnqueueReleaseGLObjects(
9008*6fee86a4SJeremy Kemp                  object_,
9009*6fee86a4SJeremy Kemp                  (mem_objects != nullptr) ? (cl_uint) mem_objects->size() : 0,
9010*6fee86a4SJeremy Kemp                  (mem_objects != nullptr && mem_objects->size() > 0) ? (const cl_mem *) &mem_objects->front(): nullptr,
9011*6fee86a4SJeremy Kemp                  (events != nullptr) ? (cl_uint) events->size() : 0,
9012*6fee86a4SJeremy Kemp                  (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
9013*6fee86a4SJeremy Kemp                  (event != nullptr) ? &tmp : nullptr),
9014*6fee86a4SJeremy Kemp              __ENQUEUE_RELEASE_GL_ERR);
9015*6fee86a4SJeremy Kemp 
9016*6fee86a4SJeremy Kemp         if (event != nullptr && err == CL_SUCCESS)
9017*6fee86a4SJeremy Kemp             *event = tmp;
9018*6fee86a4SJeremy Kemp 
9019*6fee86a4SJeremy Kemp         return err;
9020*6fee86a4SJeremy Kemp      }
9021*6fee86a4SJeremy Kemp 
9022*6fee86a4SJeremy Kemp #if defined (CL_HPP_USE_DX_INTEROP)
9023*6fee86a4SJeremy Kemp typedef CL_API_ENTRY cl_int (CL_API_CALL *PFN_clEnqueueAcquireD3D10ObjectsKHR)(
9024*6fee86a4SJeremy Kemp     cl_command_queue command_queue, cl_uint num_objects,
9025*6fee86a4SJeremy Kemp     const cl_mem* mem_objects, cl_uint num_events_in_wait_list,
9026*6fee86a4SJeremy Kemp     const cl_event* event_wait_list, cl_event* event);
9027*6fee86a4SJeremy Kemp typedef CL_API_ENTRY cl_int (CL_API_CALL *PFN_clEnqueueReleaseD3D10ObjectsKHR)(
9028*6fee86a4SJeremy Kemp     cl_command_queue command_queue, cl_uint num_objects,
9029*6fee86a4SJeremy Kemp     const cl_mem* mem_objects,  cl_uint num_events_in_wait_list,
9030*6fee86a4SJeremy Kemp     const cl_event* event_wait_list, cl_event* event);
9031*6fee86a4SJeremy Kemp 
enqueueAcquireD3D10Objects(const vector<Memory> * mem_objects=nullptr,const vector<Event> * events=nullptr,Event * event=nullptr) const9032*6fee86a4SJeremy Kemp     cl_int enqueueAcquireD3D10Objects(
9033*6fee86a4SJeremy Kemp          const vector<Memory>* mem_objects = nullptr,
9034*6fee86a4SJeremy Kemp          const vector<Event>* events = nullptr,
9035*6fee86a4SJeremy Kemp          Event* event = nullptr) const
9036*6fee86a4SJeremy Kemp     {
9037*6fee86a4SJeremy Kemp         static PFN_clEnqueueAcquireD3D10ObjectsKHR pfn_clEnqueueAcquireD3D10ObjectsKHR = nullptr;
9038*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 120
9039*6fee86a4SJeremy Kemp         cl_context context = getInfo<CL_QUEUE_CONTEXT>();
9040*6fee86a4SJeremy Kemp         cl::Device device(getInfo<CL_QUEUE_DEVICE>());
9041*6fee86a4SJeremy Kemp         cl_platform_id platform = device.getInfo<CL_DEVICE_PLATFORM>();
9042*6fee86a4SJeremy Kemp         CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clEnqueueAcquireD3D10ObjectsKHR);
9043*6fee86a4SJeremy Kemp #endif
9044*6fee86a4SJeremy Kemp #if CL_HPP_MINIMUM_OPENCL_VERSION < 120
9045*6fee86a4SJeremy Kemp         CL_HPP_INIT_CL_EXT_FCN_PTR_(clEnqueueAcquireD3D10ObjectsKHR);
9046*6fee86a4SJeremy Kemp #endif
9047*6fee86a4SJeremy Kemp 
9048*6fee86a4SJeremy Kemp         cl_event tmp;
9049*6fee86a4SJeremy Kemp         cl_int err = detail::errHandler(
9050*6fee86a4SJeremy Kemp              pfn_clEnqueueAcquireD3D10ObjectsKHR(
9051*6fee86a4SJeremy Kemp                  object_,
9052*6fee86a4SJeremy Kemp                  (mem_objects != nullptr) ? (cl_uint) mem_objects->size() : 0,
9053*6fee86a4SJeremy Kemp                  (mem_objects != nullptr && mem_objects->size() > 0) ? (const cl_mem *) &mem_objects->front(): nullptr,
9054*6fee86a4SJeremy Kemp                  (events != nullptr) ? (cl_uint) events->size() : 0,
9055*6fee86a4SJeremy Kemp                  (events != nullptr) ? (cl_event*) &events->front() : nullptr,
9056*6fee86a4SJeremy Kemp                  (event != nullptr) ? &tmp : nullptr),
9057*6fee86a4SJeremy Kemp              __ENQUEUE_ACQUIRE_GL_ERR);
9058*6fee86a4SJeremy Kemp 
9059*6fee86a4SJeremy Kemp         if (event != nullptr && err == CL_SUCCESS)
9060*6fee86a4SJeremy Kemp             *event = tmp;
9061*6fee86a4SJeremy Kemp 
9062*6fee86a4SJeremy Kemp         return err;
9063*6fee86a4SJeremy Kemp      }
9064*6fee86a4SJeremy Kemp 
enqueueReleaseD3D10Objects(const vector<Memory> * mem_objects=nullptr,const vector<Event> * events=nullptr,Event * event=nullptr) const9065*6fee86a4SJeremy Kemp     cl_int enqueueReleaseD3D10Objects(
9066*6fee86a4SJeremy Kemp          const vector<Memory>* mem_objects = nullptr,
9067*6fee86a4SJeremy Kemp          const vector<Event>* events = nullptr,
9068*6fee86a4SJeremy Kemp          Event* event = nullptr) const
9069*6fee86a4SJeremy Kemp     {
9070*6fee86a4SJeremy Kemp         static PFN_clEnqueueReleaseD3D10ObjectsKHR pfn_clEnqueueReleaseD3D10ObjectsKHR = nullptr;
9071*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 120
9072*6fee86a4SJeremy Kemp         cl_context context = getInfo<CL_QUEUE_CONTEXT>();
9073*6fee86a4SJeremy Kemp         cl::Device device(getInfo<CL_QUEUE_DEVICE>());
9074*6fee86a4SJeremy Kemp         cl_platform_id platform = device.getInfo<CL_DEVICE_PLATFORM>();
9075*6fee86a4SJeremy Kemp         CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clEnqueueReleaseD3D10ObjectsKHR);
9076*6fee86a4SJeremy Kemp #endif
9077*6fee86a4SJeremy Kemp #if CL_HPP_MINIMUM_OPENCL_VERSION < 120
9078*6fee86a4SJeremy Kemp         CL_HPP_INIT_CL_EXT_FCN_PTR_(clEnqueueReleaseD3D10ObjectsKHR);
9079*6fee86a4SJeremy Kemp #endif
9080*6fee86a4SJeremy Kemp 
9081*6fee86a4SJeremy Kemp         cl_event tmp;
9082*6fee86a4SJeremy Kemp         cl_int err = detail::errHandler(
9083*6fee86a4SJeremy Kemp             pfn_clEnqueueReleaseD3D10ObjectsKHR(
9084*6fee86a4SJeremy Kemp                 object_,
9085*6fee86a4SJeremy Kemp                 (mem_objects != nullptr) ? (cl_uint) mem_objects->size() : 0,
9086*6fee86a4SJeremy Kemp                 (mem_objects != nullptr && mem_objects->size() > 0) ? (const cl_mem *) &mem_objects->front(): nullptr,
9087*6fee86a4SJeremy Kemp                 (events != nullptr) ? (cl_uint) events->size() : 0,
9088*6fee86a4SJeremy Kemp                 (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
9089*6fee86a4SJeremy Kemp                 (event != nullptr) ? &tmp : nullptr),
9090*6fee86a4SJeremy Kemp             __ENQUEUE_RELEASE_GL_ERR);
9091*6fee86a4SJeremy Kemp 
9092*6fee86a4SJeremy Kemp         if (event != nullptr && err == CL_SUCCESS)
9093*6fee86a4SJeremy Kemp             *event = tmp;
9094*6fee86a4SJeremy Kemp 
9095*6fee86a4SJeremy Kemp         return err;
9096*6fee86a4SJeremy Kemp     }
9097*6fee86a4SJeremy Kemp #endif
9098*6fee86a4SJeremy Kemp 
9099*6fee86a4SJeremy Kemp /**
9100*6fee86a4SJeremy Kemp  * Deprecated APIs for 1.2
9101*6fee86a4SJeremy Kemp  */
9102*6fee86a4SJeremy Kemp #if defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS)
9103*6fee86a4SJeremy Kemp     CL_API_PREFIX__VERSION_1_1_DEPRECATED
enqueueBarrier() const9104*6fee86a4SJeremy Kemp     cl_int enqueueBarrier() const CL_API_SUFFIX__VERSION_1_1_DEPRECATED
9105*6fee86a4SJeremy Kemp     {
9106*6fee86a4SJeremy Kemp         return detail::errHandler(
9107*6fee86a4SJeremy Kemp             ::clEnqueueBarrier(object_),
9108*6fee86a4SJeremy Kemp             __ENQUEUE_BARRIER_ERR);
9109*6fee86a4SJeremy Kemp     }
9110*6fee86a4SJeremy Kemp #endif // CL_USE_DEPRECATED_OPENCL_1_1_APIS
9111*6fee86a4SJeremy Kemp 
flush() const9112*6fee86a4SJeremy Kemp     cl_int flush() const
9113*6fee86a4SJeremy Kemp     {
9114*6fee86a4SJeremy Kemp         return detail::errHandler(::clFlush(object_), __FLUSH_ERR);
9115*6fee86a4SJeremy Kemp     }
9116*6fee86a4SJeremy Kemp 
finish() const9117*6fee86a4SJeremy Kemp     cl_int finish() const
9118*6fee86a4SJeremy Kemp     {
9119*6fee86a4SJeremy Kemp         return detail::errHandler(::clFinish(object_), __FINISH_ERR);
9120*6fee86a4SJeremy Kemp     }
9121*6fee86a4SJeremy Kemp 
9122*6fee86a4SJeremy Kemp #ifdef cl_khr_external_memory
enqueueAcquireExternalMemObjects(const vector<Memory> & mem_objects,const vector<Event> * events_wait=nullptr,Event * event=nullptr)9123*6fee86a4SJeremy Kemp     cl_int enqueueAcquireExternalMemObjects(
9124*6fee86a4SJeremy Kemp         const vector<Memory>& mem_objects,
9125*6fee86a4SJeremy Kemp         const vector<Event>* events_wait = nullptr,
9126*6fee86a4SJeremy Kemp         Event *event = nullptr)
9127*6fee86a4SJeremy Kemp     {
9128*6fee86a4SJeremy Kemp         cl_int err = CL_INVALID_OPERATION;
9129*6fee86a4SJeremy Kemp         cl_event tmp;
9130*6fee86a4SJeremy Kemp 
9131*6fee86a4SJeremy Kemp         std::call_once(ext_memory_initialized_, initMemoryExtension, this->getInfo<CL_QUEUE_DEVICE>());
9132*6fee86a4SJeremy Kemp 
9133*6fee86a4SJeremy Kemp         if (pfn_clEnqueueAcquireExternalMemObjectsKHR)
9134*6fee86a4SJeremy Kemp         {
9135*6fee86a4SJeremy Kemp             err = pfn_clEnqueueAcquireExternalMemObjectsKHR(
9136*6fee86a4SJeremy Kemp                 object_,
9137*6fee86a4SJeremy Kemp                 static_cast<cl_uint>(mem_objects.size()),
9138*6fee86a4SJeremy Kemp                 (mem_objects.size() > 0) ? reinterpret_cast<const cl_mem *>(mem_objects.data()) : nullptr,
9139*6fee86a4SJeremy Kemp                 (events_wait != nullptr) ? static_cast<cl_uint>(events_wait->size()) : 0,
9140*6fee86a4SJeremy Kemp                 (events_wait != nullptr && events_wait->size() > 0) ? reinterpret_cast<const cl_event*>(events_wait->data()) : nullptr,
9141*6fee86a4SJeremy Kemp                 &tmp);
9142*6fee86a4SJeremy Kemp         }
9143*6fee86a4SJeremy Kemp 
9144*6fee86a4SJeremy Kemp         detail::errHandler(err, __ENQUEUE_ACQUIRE_EXTERNAL_MEMORY_ERR);
9145*6fee86a4SJeremy Kemp 
9146*6fee86a4SJeremy Kemp         if (event != nullptr && err == CL_SUCCESS)
9147*6fee86a4SJeremy Kemp             *event = tmp;
9148*6fee86a4SJeremy Kemp 
9149*6fee86a4SJeremy Kemp         return err;
9150*6fee86a4SJeremy Kemp     }
9151*6fee86a4SJeremy Kemp 
enqueueReleaseExternalMemObjects(const vector<Memory> & mem_objects,const vector<Event> * events_wait=nullptr,Event * event=nullptr)9152*6fee86a4SJeremy Kemp     cl_int enqueueReleaseExternalMemObjects(
9153*6fee86a4SJeremy Kemp         const vector<Memory>& mem_objects,
9154*6fee86a4SJeremy Kemp         const vector<Event>* events_wait = nullptr,
9155*6fee86a4SJeremy Kemp         Event *event = nullptr)
9156*6fee86a4SJeremy Kemp     {
9157*6fee86a4SJeremy Kemp         cl_int err = CL_INVALID_OPERATION;
9158*6fee86a4SJeremy Kemp         cl_event tmp;
9159*6fee86a4SJeremy Kemp 
9160*6fee86a4SJeremy Kemp         std::call_once(ext_memory_initialized_, initMemoryExtension, this->getInfo<CL_QUEUE_DEVICE>());
9161*6fee86a4SJeremy Kemp 
9162*6fee86a4SJeremy Kemp         if (pfn_clEnqueueReleaseExternalMemObjectsKHR)
9163*6fee86a4SJeremy Kemp         {
9164*6fee86a4SJeremy Kemp             err = pfn_clEnqueueReleaseExternalMemObjectsKHR(
9165*6fee86a4SJeremy Kemp                 object_,
9166*6fee86a4SJeremy Kemp                 static_cast<cl_uint>(mem_objects.size()),
9167*6fee86a4SJeremy Kemp                 (mem_objects.size() > 0) ? reinterpret_cast<const cl_mem *>(mem_objects.data()) : nullptr,
9168*6fee86a4SJeremy Kemp                 (events_wait != nullptr) ? static_cast<cl_uint>(events_wait->size()) : 0,
9169*6fee86a4SJeremy Kemp                 (events_wait != nullptr && events_wait->size() > 0) ? reinterpret_cast<const cl_event*>(events_wait->data()) : nullptr,
9170*6fee86a4SJeremy Kemp                 &tmp);
9171*6fee86a4SJeremy Kemp         }
9172*6fee86a4SJeremy Kemp 
9173*6fee86a4SJeremy Kemp         detail::errHandler(err, __ENQUEUE_RELEASE_EXTERNAL_MEMORY_ERR);
9174*6fee86a4SJeremy Kemp 
9175*6fee86a4SJeremy Kemp         if (event != nullptr && err == CL_SUCCESS)
9176*6fee86a4SJeremy Kemp             *event = tmp;
9177*6fee86a4SJeremy Kemp 
9178*6fee86a4SJeremy Kemp         return err;
9179*6fee86a4SJeremy Kemp     }
9180*6fee86a4SJeremy Kemp #endif // cl_khr_external_memory && CL_HPP_TARGET_OPENCL_VERSION >= 300
9181*6fee86a4SJeremy Kemp 
9182*6fee86a4SJeremy Kemp #ifdef cl_khr_semaphore
9183*6fee86a4SJeremy Kemp     cl_int enqueueWaitSemaphores(
9184*6fee86a4SJeremy Kemp         const vector<Semaphore> &sema_objects,
9185*6fee86a4SJeremy Kemp         const vector<cl_semaphore_payload_khr> &sema_payloads = {},
9186*6fee86a4SJeremy Kemp         const vector<Event>* events_wait_list = nullptr,
9187*6fee86a4SJeremy Kemp         Event *event = nullptr) const;
9188*6fee86a4SJeremy Kemp 
9189*6fee86a4SJeremy Kemp     cl_int enqueueSignalSemaphores(
9190*6fee86a4SJeremy Kemp         const vector<Semaphore> &sema_objects,
9191*6fee86a4SJeremy Kemp         const vector<cl_semaphore_payload_khr>& sema_payloads = {},
9192*6fee86a4SJeremy Kemp         const vector<Event>* events_wait_list = nullptr,
9193*6fee86a4SJeremy Kemp         Event* event = nullptr);
9194*6fee86a4SJeremy Kemp #endif // cl_khr_semaphore
9195*6fee86a4SJeremy Kemp }; // CommandQueue
9196*6fee86a4SJeremy Kemp 
9197*6fee86a4SJeremy Kemp #ifdef cl_khr_external_memory
9198*6fee86a4SJeremy Kemp CL_HPP_DEFINE_STATIC_MEMBER_ std::once_flag CommandQueue::ext_memory_initialized_;
9199*6fee86a4SJeremy Kemp #endif
9200*6fee86a4SJeremy Kemp 
9201*6fee86a4SJeremy Kemp CL_HPP_DEFINE_STATIC_MEMBER_ std::once_flag CommandQueue::default_initialized_;
9202*6fee86a4SJeremy Kemp CL_HPP_DEFINE_STATIC_MEMBER_ CommandQueue CommandQueue::default_;
9203*6fee86a4SJeremy Kemp CL_HPP_DEFINE_STATIC_MEMBER_ cl_int CommandQueue::default_error_ = CL_SUCCESS;
9204*6fee86a4SJeremy Kemp 
9205*6fee86a4SJeremy Kemp 
9206*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 200
9207*6fee86a4SJeremy Kemp enum class DeviceQueueProperties : cl_command_queue_properties
9208*6fee86a4SJeremy Kemp {
9209*6fee86a4SJeremy Kemp     None = 0,
9210*6fee86a4SJeremy Kemp     Profiling = CL_QUEUE_PROFILING_ENABLE,
9211*6fee86a4SJeremy Kemp };
9212*6fee86a4SJeremy Kemp 
operator |(DeviceQueueProperties lhs,DeviceQueueProperties rhs)9213*6fee86a4SJeremy Kemp inline DeviceQueueProperties operator|(DeviceQueueProperties lhs, DeviceQueueProperties rhs)
9214*6fee86a4SJeremy Kemp {
9215*6fee86a4SJeremy Kemp     return static_cast<DeviceQueueProperties>(static_cast<cl_command_queue_properties>(lhs) | static_cast<cl_command_queue_properties>(rhs));
9216*6fee86a4SJeremy Kemp }
9217*6fee86a4SJeremy Kemp 
9218*6fee86a4SJeremy Kemp /*! \class DeviceCommandQueue
9219*6fee86a4SJeremy Kemp  * \brief DeviceCommandQueue interface for device cl_command_queues.
9220*6fee86a4SJeremy Kemp  */
9221*6fee86a4SJeremy Kemp class DeviceCommandQueue : public detail::Wrapper<cl_command_queue>
9222*6fee86a4SJeremy Kemp {
9223*6fee86a4SJeremy Kemp public:
9224*6fee86a4SJeremy Kemp 
9225*6fee86a4SJeremy Kemp     /*!
9226*6fee86a4SJeremy Kemp      * Trivial empty constructor to create a null queue.
9227*6fee86a4SJeremy Kemp      */
DeviceCommandQueue()9228*6fee86a4SJeremy Kemp     DeviceCommandQueue() { }
9229*6fee86a4SJeremy Kemp 
9230*6fee86a4SJeremy Kemp     /*!
9231*6fee86a4SJeremy Kemp      * Default construct device command queue on default context and device
9232*6fee86a4SJeremy Kemp      */
DeviceCommandQueue(DeviceQueueProperties properties,cl_int * err=nullptr)9233*6fee86a4SJeremy Kemp     DeviceCommandQueue(DeviceQueueProperties properties, cl_int* err = nullptr)
9234*6fee86a4SJeremy Kemp     {
9235*6fee86a4SJeremy Kemp         cl_int error;
9236*6fee86a4SJeremy Kemp         cl::Context context = cl::Context::getDefault();
9237*6fee86a4SJeremy Kemp         cl::Device device = cl::Device::getDefault();
9238*6fee86a4SJeremy Kemp 
9239*6fee86a4SJeremy Kemp         cl_command_queue_properties mergedProperties =
9240*6fee86a4SJeremy Kemp             CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE | CL_QUEUE_ON_DEVICE | static_cast<cl_command_queue_properties>(properties);
9241*6fee86a4SJeremy Kemp 
9242*6fee86a4SJeremy Kemp         cl_queue_properties queue_properties[] = {
9243*6fee86a4SJeremy Kemp             CL_QUEUE_PROPERTIES, mergedProperties, 0 };
9244*6fee86a4SJeremy Kemp         object_ = ::clCreateCommandQueueWithProperties(
9245*6fee86a4SJeremy Kemp             context(), device(), queue_properties, &error);
9246*6fee86a4SJeremy Kemp 
9247*6fee86a4SJeremy Kemp         detail::errHandler(error, __CREATE_COMMAND_QUEUE_WITH_PROPERTIES_ERR);
9248*6fee86a4SJeremy Kemp         if (err != nullptr) {
9249*6fee86a4SJeremy Kemp             *err = error;
9250*6fee86a4SJeremy Kemp         }
9251*6fee86a4SJeremy Kemp     }
9252*6fee86a4SJeremy Kemp 
9253*6fee86a4SJeremy Kemp     /*!
9254*6fee86a4SJeremy Kemp      * Create a device command queue for a specified device in the passed context.
9255*6fee86a4SJeremy Kemp      */
DeviceCommandQueue(const Context & context,const Device & device,DeviceQueueProperties properties=DeviceQueueProperties::None,cl_int * err=nullptr)9256*6fee86a4SJeremy Kemp     DeviceCommandQueue(
9257*6fee86a4SJeremy Kemp         const Context& context,
9258*6fee86a4SJeremy Kemp         const Device& device,
9259*6fee86a4SJeremy Kemp         DeviceQueueProperties properties = DeviceQueueProperties::None,
9260*6fee86a4SJeremy Kemp         cl_int* err = nullptr)
9261*6fee86a4SJeremy Kemp     {
9262*6fee86a4SJeremy Kemp         cl_int error;
9263*6fee86a4SJeremy Kemp 
9264*6fee86a4SJeremy Kemp         cl_command_queue_properties mergedProperties =
9265*6fee86a4SJeremy Kemp             CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE | CL_QUEUE_ON_DEVICE | static_cast<cl_command_queue_properties>(properties);
9266*6fee86a4SJeremy Kemp         cl_queue_properties queue_properties[] = {
9267*6fee86a4SJeremy Kemp             CL_QUEUE_PROPERTIES, mergedProperties, 0 };
9268*6fee86a4SJeremy Kemp         object_ = ::clCreateCommandQueueWithProperties(
9269*6fee86a4SJeremy Kemp             context(), device(), queue_properties, &error);
9270*6fee86a4SJeremy Kemp 
9271*6fee86a4SJeremy Kemp         detail::errHandler(error, __CREATE_COMMAND_QUEUE_WITH_PROPERTIES_ERR);
9272*6fee86a4SJeremy Kemp         if (err != nullptr) {
9273*6fee86a4SJeremy Kemp             *err = error;
9274*6fee86a4SJeremy Kemp         }
9275*6fee86a4SJeremy Kemp     }
9276*6fee86a4SJeremy Kemp 
9277*6fee86a4SJeremy Kemp     /*!
9278*6fee86a4SJeremy Kemp      * Create a device command queue for a specified device in the passed context.
9279*6fee86a4SJeremy Kemp      */
DeviceCommandQueue(const Context & context,const Device & device,cl_uint queueSize,DeviceQueueProperties properties=DeviceQueueProperties::None,cl_int * err=nullptr)9280*6fee86a4SJeremy Kemp     DeviceCommandQueue(
9281*6fee86a4SJeremy Kemp         const Context& context,
9282*6fee86a4SJeremy Kemp         const Device& device,
9283*6fee86a4SJeremy Kemp         cl_uint queueSize,
9284*6fee86a4SJeremy Kemp         DeviceQueueProperties properties = DeviceQueueProperties::None,
9285*6fee86a4SJeremy Kemp         cl_int* err = nullptr)
9286*6fee86a4SJeremy Kemp     {
9287*6fee86a4SJeremy Kemp         cl_int error;
9288*6fee86a4SJeremy Kemp 
9289*6fee86a4SJeremy Kemp         cl_command_queue_properties mergedProperties =
9290*6fee86a4SJeremy Kemp             CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE | CL_QUEUE_ON_DEVICE | static_cast<cl_command_queue_properties>(properties);
9291*6fee86a4SJeremy Kemp         cl_queue_properties queue_properties[] = {
9292*6fee86a4SJeremy Kemp             CL_QUEUE_PROPERTIES, mergedProperties,
9293*6fee86a4SJeremy Kemp             CL_QUEUE_SIZE, queueSize,
9294*6fee86a4SJeremy Kemp             0 };
9295*6fee86a4SJeremy Kemp         object_ = ::clCreateCommandQueueWithProperties(
9296*6fee86a4SJeremy Kemp             context(), device(), queue_properties, &error);
9297*6fee86a4SJeremy Kemp 
9298*6fee86a4SJeremy Kemp         detail::errHandler(error, __CREATE_COMMAND_QUEUE_WITH_PROPERTIES_ERR);
9299*6fee86a4SJeremy Kemp         if (err != nullptr) {
9300*6fee86a4SJeremy Kemp             *err = error;
9301*6fee86a4SJeremy Kemp         }
9302*6fee86a4SJeremy Kemp     }
9303*6fee86a4SJeremy Kemp 
9304*6fee86a4SJeremy Kemp     /*! \brief Constructor from cl_command_queue - takes ownership.
9305*6fee86a4SJeremy Kemp     *
9306*6fee86a4SJeremy Kemp     * \param retainObject will cause the constructor to retain its cl object.
9307*6fee86a4SJeremy Kemp     *                     Defaults to false to maintain compatibility with
9308*6fee86a4SJeremy Kemp     *                     earlier versions.
9309*6fee86a4SJeremy Kemp     */
DeviceCommandQueue(const cl_command_queue & commandQueue,bool retainObject=false)9310*6fee86a4SJeremy Kemp     explicit DeviceCommandQueue(const cl_command_queue& commandQueue, bool retainObject = false) :
9311*6fee86a4SJeremy Kemp         detail::Wrapper<cl_type>(commandQueue, retainObject) { }
9312*6fee86a4SJeremy Kemp 
operator =(const cl_command_queue & rhs)9313*6fee86a4SJeremy Kemp     DeviceCommandQueue& operator = (const cl_command_queue& rhs)
9314*6fee86a4SJeremy Kemp     {
9315*6fee86a4SJeremy Kemp         detail::Wrapper<cl_type>::operator=(rhs);
9316*6fee86a4SJeremy Kemp         return *this;
9317*6fee86a4SJeremy Kemp     }
9318*6fee86a4SJeremy Kemp 
9319*6fee86a4SJeremy Kemp     template <typename T>
getInfo(cl_command_queue_info name,T * param) const9320*6fee86a4SJeremy Kemp     cl_int getInfo(cl_command_queue_info name, T* param) const
9321*6fee86a4SJeremy Kemp     {
9322*6fee86a4SJeremy Kemp         return detail::errHandler(
9323*6fee86a4SJeremy Kemp             detail::getInfo(
9324*6fee86a4SJeremy Kemp             &::clGetCommandQueueInfo, object_, name, param),
9325*6fee86a4SJeremy Kemp             __GET_COMMAND_QUEUE_INFO_ERR);
9326*6fee86a4SJeremy Kemp     }
9327*6fee86a4SJeremy Kemp 
9328*6fee86a4SJeremy Kemp     template <cl_command_queue_info name> typename
9329*6fee86a4SJeremy Kemp         detail::param_traits<detail::cl_command_queue_info, name>::param_type
getInfo(cl_int * err=nullptr) const9330*6fee86a4SJeremy Kemp         getInfo(cl_int* err = nullptr) const
9331*6fee86a4SJeremy Kemp     {
9332*6fee86a4SJeremy Kemp         typename detail::param_traits<
9333*6fee86a4SJeremy Kemp             detail::cl_command_queue_info, name>::param_type param;
9334*6fee86a4SJeremy Kemp         cl_int result = getInfo(name, &param);
9335*6fee86a4SJeremy Kemp         if (err != nullptr) {
9336*6fee86a4SJeremy Kemp             *err = result;
9337*6fee86a4SJeremy Kemp         }
9338*6fee86a4SJeremy Kemp         return param;
9339*6fee86a4SJeremy Kemp     }
9340*6fee86a4SJeremy Kemp 
9341*6fee86a4SJeremy Kemp     /*!
9342*6fee86a4SJeremy Kemp      * Create a new default device command queue for the default device,
9343*6fee86a4SJeremy Kemp      * in the default context and of the default size.
9344*6fee86a4SJeremy Kemp      * If there is already a default queue for the specified device this
9345*6fee86a4SJeremy Kemp      * function will return the pre-existing queue.
9346*6fee86a4SJeremy Kemp      */
makeDefault(cl_int * err=nullptr)9347*6fee86a4SJeremy Kemp     static DeviceCommandQueue makeDefault(
9348*6fee86a4SJeremy Kemp         cl_int *err = nullptr)
9349*6fee86a4SJeremy Kemp     {
9350*6fee86a4SJeremy Kemp         cl_int error;
9351*6fee86a4SJeremy Kemp         cl::Context context = cl::Context::getDefault();
9352*6fee86a4SJeremy Kemp         cl::Device device = cl::Device::getDefault();
9353*6fee86a4SJeremy Kemp 
9354*6fee86a4SJeremy Kemp         cl_command_queue_properties properties =
9355*6fee86a4SJeremy Kemp             CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE | CL_QUEUE_ON_DEVICE | CL_QUEUE_ON_DEVICE_DEFAULT;
9356*6fee86a4SJeremy Kemp         cl_queue_properties queue_properties[] = {
9357*6fee86a4SJeremy Kemp             CL_QUEUE_PROPERTIES, properties,
9358*6fee86a4SJeremy Kemp             0 };
9359*6fee86a4SJeremy Kemp         DeviceCommandQueue deviceQueue(
9360*6fee86a4SJeremy Kemp             ::clCreateCommandQueueWithProperties(
9361*6fee86a4SJeremy Kemp             context(), device(), queue_properties, &error));
9362*6fee86a4SJeremy Kemp 
9363*6fee86a4SJeremy Kemp         detail::errHandler(error, __CREATE_COMMAND_QUEUE_WITH_PROPERTIES_ERR);
9364*6fee86a4SJeremy Kemp         if (err != nullptr) {
9365*6fee86a4SJeremy Kemp             *err = error;
9366*6fee86a4SJeremy Kemp         }
9367*6fee86a4SJeremy Kemp 
9368*6fee86a4SJeremy Kemp         return deviceQueue;
9369*6fee86a4SJeremy Kemp     }
9370*6fee86a4SJeremy Kemp 
9371*6fee86a4SJeremy Kemp     /*!
9372*6fee86a4SJeremy Kemp      * Create a new default device command queue for the specified device
9373*6fee86a4SJeremy Kemp      * and of the default size.
9374*6fee86a4SJeremy Kemp      * If there is already a default queue for the specified device this
9375*6fee86a4SJeremy Kemp      * function will return the pre-existing queue.
9376*6fee86a4SJeremy Kemp      */
makeDefault(const Context & context,const Device & device,cl_int * err=nullptr)9377*6fee86a4SJeremy Kemp     static DeviceCommandQueue makeDefault(
9378*6fee86a4SJeremy Kemp         const Context &context, const Device &device, cl_int *err = nullptr)
9379*6fee86a4SJeremy Kemp     {
9380*6fee86a4SJeremy Kemp         cl_int error;
9381*6fee86a4SJeremy Kemp 
9382*6fee86a4SJeremy Kemp         cl_command_queue_properties properties =
9383*6fee86a4SJeremy Kemp             CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE | CL_QUEUE_ON_DEVICE | CL_QUEUE_ON_DEVICE_DEFAULT;
9384*6fee86a4SJeremy Kemp         cl_queue_properties queue_properties[] = {
9385*6fee86a4SJeremy Kemp             CL_QUEUE_PROPERTIES, properties,
9386*6fee86a4SJeremy Kemp             0 };
9387*6fee86a4SJeremy Kemp         DeviceCommandQueue deviceQueue(
9388*6fee86a4SJeremy Kemp             ::clCreateCommandQueueWithProperties(
9389*6fee86a4SJeremy Kemp             context(), device(), queue_properties, &error));
9390*6fee86a4SJeremy Kemp 
9391*6fee86a4SJeremy Kemp         detail::errHandler(error, __CREATE_COMMAND_QUEUE_WITH_PROPERTIES_ERR);
9392*6fee86a4SJeremy Kemp         if (err != nullptr) {
9393*6fee86a4SJeremy Kemp             *err = error;
9394*6fee86a4SJeremy Kemp         }
9395*6fee86a4SJeremy Kemp 
9396*6fee86a4SJeremy Kemp         return deviceQueue;
9397*6fee86a4SJeremy Kemp     }
9398*6fee86a4SJeremy Kemp 
9399*6fee86a4SJeremy Kemp     /*!
9400*6fee86a4SJeremy Kemp      * Create a new default device command queue for the specified device
9401*6fee86a4SJeremy Kemp      * and of the requested size in bytes.
9402*6fee86a4SJeremy Kemp      * If there is already a default queue for the specified device this
9403*6fee86a4SJeremy Kemp      * function will return the pre-existing queue.
9404*6fee86a4SJeremy Kemp      */
makeDefault(const Context & context,const Device & device,cl_uint queueSize,cl_int * err=nullptr)9405*6fee86a4SJeremy Kemp     static DeviceCommandQueue makeDefault(
9406*6fee86a4SJeremy Kemp         const Context &context, const Device &device, cl_uint queueSize, cl_int *err = nullptr)
9407*6fee86a4SJeremy Kemp     {
9408*6fee86a4SJeremy Kemp         cl_int error;
9409*6fee86a4SJeremy Kemp 
9410*6fee86a4SJeremy Kemp         cl_command_queue_properties properties =
9411*6fee86a4SJeremy Kemp             CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE | CL_QUEUE_ON_DEVICE | CL_QUEUE_ON_DEVICE_DEFAULT;
9412*6fee86a4SJeremy Kemp         cl_queue_properties queue_properties[] = {
9413*6fee86a4SJeremy Kemp             CL_QUEUE_PROPERTIES, properties,
9414*6fee86a4SJeremy Kemp             CL_QUEUE_SIZE, queueSize,
9415*6fee86a4SJeremy Kemp             0 };
9416*6fee86a4SJeremy Kemp         DeviceCommandQueue deviceQueue(
9417*6fee86a4SJeremy Kemp             ::clCreateCommandQueueWithProperties(
9418*6fee86a4SJeremy Kemp                 context(), device(), queue_properties, &error));
9419*6fee86a4SJeremy Kemp 
9420*6fee86a4SJeremy Kemp         detail::errHandler(error, __CREATE_COMMAND_QUEUE_WITH_PROPERTIES_ERR);
9421*6fee86a4SJeremy Kemp         if (err != nullptr) {
9422*6fee86a4SJeremy Kemp             *err = error;
9423*6fee86a4SJeremy Kemp         }
9424*6fee86a4SJeremy Kemp 
9425*6fee86a4SJeremy Kemp         return deviceQueue;
9426*6fee86a4SJeremy Kemp     }
9427*6fee86a4SJeremy Kemp 
9428*6fee86a4SJeremy Kemp 
9429*6fee86a4SJeremy Kemp 
9430*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 210
9431*6fee86a4SJeremy Kemp     /*!
9432*6fee86a4SJeremy Kemp      * Modify the default device command queue to be used for subsequent kernels.
9433*6fee86a4SJeremy Kemp      * This can update the default command queue for a device repeatedly to account
9434*6fee86a4SJeremy Kemp      * for kernels that rely on the default.
9435*6fee86a4SJeremy Kemp      * @return updated default device command queue.
9436*6fee86a4SJeremy Kemp      */
updateDefault(const Context & context,const Device & device,const DeviceCommandQueue & default_queue,cl_int * err=nullptr)9437*6fee86a4SJeremy Kemp     static DeviceCommandQueue updateDefault(const Context &context, const Device &device, const DeviceCommandQueue &default_queue, cl_int *err = nullptr)
9438*6fee86a4SJeremy Kemp     {
9439*6fee86a4SJeremy Kemp         cl_int error;
9440*6fee86a4SJeremy Kemp         error = clSetDefaultDeviceCommandQueue(context.get(), device.get(), default_queue.get());
9441*6fee86a4SJeremy Kemp 
9442*6fee86a4SJeremy Kemp         detail::errHandler(error, __SET_DEFAULT_DEVICE_COMMAND_QUEUE_ERR);
9443*6fee86a4SJeremy Kemp         if (err != nullptr) {
9444*6fee86a4SJeremy Kemp             *err = error;
9445*6fee86a4SJeremy Kemp         }
9446*6fee86a4SJeremy Kemp         return default_queue;
9447*6fee86a4SJeremy Kemp     }
9448*6fee86a4SJeremy Kemp 
9449*6fee86a4SJeremy Kemp     /*!
9450*6fee86a4SJeremy Kemp      * Return the current default command queue for the specified command queue
9451*6fee86a4SJeremy Kemp      */
getDefault(const CommandQueue & queue,cl_int * err=nullptr)9452*6fee86a4SJeremy Kemp     static DeviceCommandQueue getDefault(const CommandQueue &queue, cl_int * err = nullptr)
9453*6fee86a4SJeremy Kemp     {
9454*6fee86a4SJeremy Kemp         return queue.getInfo<CL_QUEUE_DEVICE_DEFAULT>(err);
9455*6fee86a4SJeremy Kemp     }
9456*6fee86a4SJeremy Kemp 
9457*6fee86a4SJeremy Kemp #endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 210
9458*6fee86a4SJeremy Kemp }; // DeviceCommandQueue
9459*6fee86a4SJeremy Kemp 
9460*6fee86a4SJeremy Kemp namespace detail
9461*6fee86a4SJeremy Kemp {
9462*6fee86a4SJeremy Kemp     // Specialization for device command queue
9463*6fee86a4SJeremy Kemp     template <>
9464*6fee86a4SJeremy Kemp     struct KernelArgumentHandler<cl::DeviceCommandQueue, void>
9465*6fee86a4SJeremy Kemp     {
sizecl::detail::KernelArgumentHandler9466*6fee86a4SJeremy Kemp         static size_type size(const cl::DeviceCommandQueue&) { return sizeof(cl_command_queue); }
ptrcl::detail::KernelArgumentHandler9467*6fee86a4SJeremy Kemp         static const cl_command_queue* ptr(const cl::DeviceCommandQueue& value) { return &(value()); }
9468*6fee86a4SJeremy Kemp     };
9469*6fee86a4SJeremy Kemp } // namespace detail
9470*6fee86a4SJeremy Kemp 
9471*6fee86a4SJeremy Kemp #endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 200
9472*6fee86a4SJeremy Kemp 
9473*6fee86a4SJeremy Kemp 
9474*6fee86a4SJeremy Kemp template< typename IteratorType >
Buffer(const Context & context,IteratorType startIterator,IteratorType endIterator,bool readOnly,bool useHostPtr,cl_int * err)9475*6fee86a4SJeremy Kemp Buffer::Buffer(
9476*6fee86a4SJeremy Kemp     const Context &context,
9477*6fee86a4SJeremy Kemp     IteratorType startIterator,
9478*6fee86a4SJeremy Kemp     IteratorType endIterator,
9479*6fee86a4SJeremy Kemp     bool readOnly,
9480*6fee86a4SJeremy Kemp     bool useHostPtr,
9481*6fee86a4SJeremy Kemp     cl_int* err)
9482*6fee86a4SJeremy Kemp {
9483*6fee86a4SJeremy Kemp     typedef typename std::iterator_traits<IteratorType>::value_type DataType;
9484*6fee86a4SJeremy Kemp     cl_int error;
9485*6fee86a4SJeremy Kemp 
9486*6fee86a4SJeremy Kemp     cl_mem_flags flags = 0;
9487*6fee86a4SJeremy Kemp     if( readOnly ) {
9488*6fee86a4SJeremy Kemp         flags |= CL_MEM_READ_ONLY;
9489*6fee86a4SJeremy Kemp     }
9490*6fee86a4SJeremy Kemp     else {
9491*6fee86a4SJeremy Kemp         flags |= CL_MEM_READ_WRITE;
9492*6fee86a4SJeremy Kemp     }
9493*6fee86a4SJeremy Kemp     if( useHostPtr ) {
9494*6fee86a4SJeremy Kemp         flags |= CL_MEM_USE_HOST_PTR;
9495*6fee86a4SJeremy Kemp     }
9496*6fee86a4SJeremy Kemp 
9497*6fee86a4SJeremy Kemp     size_type size = sizeof(DataType)*(endIterator - startIterator);
9498*6fee86a4SJeremy Kemp 
9499*6fee86a4SJeremy Kemp     if( useHostPtr ) {
9500*6fee86a4SJeremy Kemp         object_ = ::clCreateBuffer(context(), flags, size, const_cast<DataType*>(&*startIterator), &error);
9501*6fee86a4SJeremy Kemp     } else {
9502*6fee86a4SJeremy Kemp         object_ = ::clCreateBuffer(context(), flags, size, 0, &error);
9503*6fee86a4SJeremy Kemp     }
9504*6fee86a4SJeremy Kemp 
9505*6fee86a4SJeremy Kemp     detail::errHandler(error, __CREATE_BUFFER_ERR);
9506*6fee86a4SJeremy Kemp     if (err != nullptr) {
9507*6fee86a4SJeremy Kemp         *err = error;
9508*6fee86a4SJeremy Kemp     }
9509*6fee86a4SJeremy Kemp 
9510*6fee86a4SJeremy Kemp     if( !useHostPtr ) {
9511*6fee86a4SJeremy Kemp         CommandQueue queue(context, 0, &error);
9512*6fee86a4SJeremy Kemp         detail::errHandler(error, __CREATE_BUFFER_ERR);
9513*6fee86a4SJeremy Kemp         if (err != nullptr) {
9514*6fee86a4SJeremy Kemp             *err = error;
9515*6fee86a4SJeremy Kemp         }
9516*6fee86a4SJeremy Kemp 
9517*6fee86a4SJeremy Kemp         error = cl::copy(queue, startIterator, endIterator, *this);
9518*6fee86a4SJeremy Kemp         detail::errHandler(error, __CREATE_BUFFER_ERR);
9519*6fee86a4SJeremy Kemp         if (err != nullptr) {
9520*6fee86a4SJeremy Kemp             *err = error;
9521*6fee86a4SJeremy Kemp         }
9522*6fee86a4SJeremy Kemp     }
9523*6fee86a4SJeremy Kemp }
9524*6fee86a4SJeremy Kemp 
9525*6fee86a4SJeremy Kemp template< typename IteratorType >
Buffer(const CommandQueue & queue,IteratorType startIterator,IteratorType endIterator,bool readOnly,bool useHostPtr,cl_int * err)9526*6fee86a4SJeremy Kemp Buffer::Buffer(
9527*6fee86a4SJeremy Kemp     const CommandQueue &queue,
9528*6fee86a4SJeremy Kemp     IteratorType startIterator,
9529*6fee86a4SJeremy Kemp     IteratorType endIterator,
9530*6fee86a4SJeremy Kemp     bool readOnly,
9531*6fee86a4SJeremy Kemp     bool useHostPtr,
9532*6fee86a4SJeremy Kemp     cl_int* err)
9533*6fee86a4SJeremy Kemp {
9534*6fee86a4SJeremy Kemp     typedef typename std::iterator_traits<IteratorType>::value_type DataType;
9535*6fee86a4SJeremy Kemp     cl_int error;
9536*6fee86a4SJeremy Kemp 
9537*6fee86a4SJeremy Kemp     cl_mem_flags flags = 0;
9538*6fee86a4SJeremy Kemp     if (readOnly) {
9539*6fee86a4SJeremy Kemp         flags |= CL_MEM_READ_ONLY;
9540*6fee86a4SJeremy Kemp     }
9541*6fee86a4SJeremy Kemp     else {
9542*6fee86a4SJeremy Kemp         flags |= CL_MEM_READ_WRITE;
9543*6fee86a4SJeremy Kemp     }
9544*6fee86a4SJeremy Kemp     if (useHostPtr) {
9545*6fee86a4SJeremy Kemp         flags |= CL_MEM_USE_HOST_PTR;
9546*6fee86a4SJeremy Kemp     }
9547*6fee86a4SJeremy Kemp 
9548*6fee86a4SJeremy Kemp     size_type size = sizeof(DataType)*(endIterator - startIterator);
9549*6fee86a4SJeremy Kemp 
9550*6fee86a4SJeremy Kemp     Context context = queue.getInfo<CL_QUEUE_CONTEXT>();
9551*6fee86a4SJeremy Kemp 
9552*6fee86a4SJeremy Kemp     if (useHostPtr) {
9553*6fee86a4SJeremy Kemp         object_ = ::clCreateBuffer(context(), flags, size, const_cast<DataType*>(&*startIterator), &error);
9554*6fee86a4SJeremy Kemp     }
9555*6fee86a4SJeremy Kemp     else {
9556*6fee86a4SJeremy Kemp         object_ = ::clCreateBuffer(context(), flags, size, 0, &error);
9557*6fee86a4SJeremy Kemp     }
9558*6fee86a4SJeremy Kemp 
9559*6fee86a4SJeremy Kemp     detail::errHandler(error, __CREATE_BUFFER_ERR);
9560*6fee86a4SJeremy Kemp     if (err != nullptr) {
9561*6fee86a4SJeremy Kemp         *err = error;
9562*6fee86a4SJeremy Kemp     }
9563*6fee86a4SJeremy Kemp 
9564*6fee86a4SJeremy Kemp     if (!useHostPtr) {
9565*6fee86a4SJeremy Kemp         error = cl::copy(queue, startIterator, endIterator, *this);
9566*6fee86a4SJeremy Kemp         detail::errHandler(error, __CREATE_BUFFER_ERR);
9567*6fee86a4SJeremy Kemp         if (err != nullptr) {
9568*6fee86a4SJeremy Kemp             *err = error;
9569*6fee86a4SJeremy Kemp         }
9570*6fee86a4SJeremy Kemp     }
9571*6fee86a4SJeremy Kemp }
9572*6fee86a4SJeremy Kemp 
enqueueReadBuffer(const Buffer & buffer,cl_bool blocking,size_type offset,size_type size,void * ptr,const vector<Event> * events=nullptr,Event * event=nullptr)9573*6fee86a4SJeremy Kemp inline cl_int enqueueReadBuffer(
9574*6fee86a4SJeremy Kemp     const Buffer& buffer,
9575*6fee86a4SJeremy Kemp     cl_bool blocking,
9576*6fee86a4SJeremy Kemp     size_type offset,
9577*6fee86a4SJeremy Kemp     size_type size,
9578*6fee86a4SJeremy Kemp     void* ptr,
9579*6fee86a4SJeremy Kemp     const vector<Event>* events = nullptr,
9580*6fee86a4SJeremy Kemp     Event* event = nullptr)
9581*6fee86a4SJeremy Kemp {
9582*6fee86a4SJeremy Kemp     cl_int error;
9583*6fee86a4SJeremy Kemp     CommandQueue queue = CommandQueue::getDefault(&error);
9584*6fee86a4SJeremy Kemp 
9585*6fee86a4SJeremy Kemp     if (error != CL_SUCCESS) {
9586*6fee86a4SJeremy Kemp         return error;
9587*6fee86a4SJeremy Kemp     }
9588*6fee86a4SJeremy Kemp 
9589*6fee86a4SJeremy Kemp     return queue.enqueueReadBuffer(buffer, blocking, offset, size, ptr, events, event);
9590*6fee86a4SJeremy Kemp }
9591*6fee86a4SJeremy Kemp 
enqueueWriteBuffer(const Buffer & buffer,cl_bool blocking,size_type offset,size_type size,const void * ptr,const vector<Event> * events=nullptr,Event * event=nullptr)9592*6fee86a4SJeremy Kemp inline cl_int enqueueWriteBuffer(
9593*6fee86a4SJeremy Kemp         const Buffer& buffer,
9594*6fee86a4SJeremy Kemp         cl_bool blocking,
9595*6fee86a4SJeremy Kemp         size_type offset,
9596*6fee86a4SJeremy Kemp         size_type size,
9597*6fee86a4SJeremy Kemp         const void* ptr,
9598*6fee86a4SJeremy Kemp         const vector<Event>* events = nullptr,
9599*6fee86a4SJeremy Kemp         Event* event = nullptr)
9600*6fee86a4SJeremy Kemp {
9601*6fee86a4SJeremy Kemp     cl_int error;
9602*6fee86a4SJeremy Kemp     CommandQueue queue = CommandQueue::getDefault(&error);
9603*6fee86a4SJeremy Kemp 
9604*6fee86a4SJeremy Kemp     if (error != CL_SUCCESS) {
9605*6fee86a4SJeremy Kemp         return error;
9606*6fee86a4SJeremy Kemp     }
9607*6fee86a4SJeremy Kemp 
9608*6fee86a4SJeremy Kemp     return queue.enqueueWriteBuffer(buffer, blocking, offset, size, ptr, events, event);
9609*6fee86a4SJeremy Kemp }
9610*6fee86a4SJeremy Kemp 
enqueueMapBuffer(const Buffer & buffer,cl_bool blocking,cl_map_flags flags,size_type offset,size_type size,const vector<Event> * events=nullptr,Event * event=nullptr,cl_int * err=nullptr)9611*6fee86a4SJeremy Kemp inline void* enqueueMapBuffer(
9612*6fee86a4SJeremy Kemp         const Buffer& buffer,
9613*6fee86a4SJeremy Kemp         cl_bool blocking,
9614*6fee86a4SJeremy Kemp         cl_map_flags flags,
9615*6fee86a4SJeremy Kemp         size_type offset,
9616*6fee86a4SJeremy Kemp         size_type size,
9617*6fee86a4SJeremy Kemp         const vector<Event>* events = nullptr,
9618*6fee86a4SJeremy Kemp         Event* event = nullptr,
9619*6fee86a4SJeremy Kemp         cl_int* err = nullptr)
9620*6fee86a4SJeremy Kemp {
9621*6fee86a4SJeremy Kemp     cl_int error;
9622*6fee86a4SJeremy Kemp     CommandQueue queue = CommandQueue::getDefault(&error);
9623*6fee86a4SJeremy Kemp     detail::errHandler(error, __ENQUEUE_MAP_BUFFER_ERR);
9624*6fee86a4SJeremy Kemp     if (err != nullptr) {
9625*6fee86a4SJeremy Kemp         *err = error;
9626*6fee86a4SJeremy Kemp     }
9627*6fee86a4SJeremy Kemp 
9628*6fee86a4SJeremy Kemp     void * result = ::clEnqueueMapBuffer(
9629*6fee86a4SJeremy Kemp             queue(), buffer(), blocking, flags, offset, size,
9630*6fee86a4SJeremy Kemp             (events != nullptr) ? (cl_uint) events->size() : 0,
9631*6fee86a4SJeremy Kemp             (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
9632*6fee86a4SJeremy Kemp             (cl_event*) event,
9633*6fee86a4SJeremy Kemp             &error);
9634*6fee86a4SJeremy Kemp 
9635*6fee86a4SJeremy Kemp     detail::errHandler(error, __ENQUEUE_MAP_BUFFER_ERR);
9636*6fee86a4SJeremy Kemp     if (err != nullptr) {
9637*6fee86a4SJeremy Kemp         *err = error;
9638*6fee86a4SJeremy Kemp     }
9639*6fee86a4SJeremy Kemp     return result;
9640*6fee86a4SJeremy Kemp }
9641*6fee86a4SJeremy Kemp 
9642*6fee86a4SJeremy Kemp 
9643*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 200
9644*6fee86a4SJeremy Kemp /**
9645*6fee86a4SJeremy Kemp  * Enqueues to the default queue a command that will allow the host to
9646*6fee86a4SJeremy Kemp  * update a region of a coarse-grained SVM buffer.
9647*6fee86a4SJeremy Kemp  * This variant takes a raw SVM pointer.
9648*6fee86a4SJeremy Kemp  */
9649*6fee86a4SJeremy Kemp template<typename T>
enqueueMapSVM(T * ptr,cl_bool blocking,cl_map_flags flags,size_type size,const vector<Event> * events,Event * event)9650*6fee86a4SJeremy Kemp inline cl_int enqueueMapSVM(
9651*6fee86a4SJeremy Kemp     T* ptr,
9652*6fee86a4SJeremy Kemp     cl_bool blocking,
9653*6fee86a4SJeremy Kemp     cl_map_flags flags,
9654*6fee86a4SJeremy Kemp     size_type size,
9655*6fee86a4SJeremy Kemp     const vector<Event>* events,
9656*6fee86a4SJeremy Kemp     Event* event)
9657*6fee86a4SJeremy Kemp {
9658*6fee86a4SJeremy Kemp     cl_int error;
9659*6fee86a4SJeremy Kemp     CommandQueue queue = CommandQueue::getDefault(&error);
9660*6fee86a4SJeremy Kemp     if (error != CL_SUCCESS) {
9661*6fee86a4SJeremy Kemp         return detail::errHandler(error, __ENQUEUE_MAP_SVM_ERR);
9662*6fee86a4SJeremy Kemp     }
9663*6fee86a4SJeremy Kemp 
9664*6fee86a4SJeremy Kemp     return queue.enqueueMapSVM(
9665*6fee86a4SJeremy Kemp         ptr, blocking, flags, size, events, event);
9666*6fee86a4SJeremy Kemp }
9667*6fee86a4SJeremy Kemp 
9668*6fee86a4SJeremy Kemp /**
9669*6fee86a4SJeremy Kemp  * Enqueues to the default queue a command that will allow the host to
9670*6fee86a4SJeremy Kemp  * update a region of a coarse-grained SVM buffer.
9671*6fee86a4SJeremy Kemp  * This variant takes a cl::pointer instance.
9672*6fee86a4SJeremy Kemp  */
9673*6fee86a4SJeremy Kemp template<typename T, class D>
enqueueMapSVM(cl::pointer<T,D> & ptr,cl_bool blocking,cl_map_flags flags,size_type size,const vector<Event> * events=nullptr,Event * event=nullptr)9674*6fee86a4SJeremy Kemp inline cl_int enqueueMapSVM(
9675*6fee86a4SJeremy Kemp     cl::pointer<T, D> &ptr,
9676*6fee86a4SJeremy Kemp     cl_bool blocking,
9677*6fee86a4SJeremy Kemp     cl_map_flags flags,
9678*6fee86a4SJeremy Kemp     size_type size,
9679*6fee86a4SJeremy Kemp     const vector<Event>* events = nullptr,
9680*6fee86a4SJeremy Kemp     Event* event = nullptr)
9681*6fee86a4SJeremy Kemp {
9682*6fee86a4SJeremy Kemp     cl_int error;
9683*6fee86a4SJeremy Kemp     CommandQueue queue = CommandQueue::getDefault(&error);
9684*6fee86a4SJeremy Kemp     if (error != CL_SUCCESS) {
9685*6fee86a4SJeremy Kemp         return detail::errHandler(error, __ENQUEUE_MAP_BUFFER_ERR);
9686*6fee86a4SJeremy Kemp     }
9687*6fee86a4SJeremy Kemp 
9688*6fee86a4SJeremy Kemp     return queue.enqueueMapSVM(
9689*6fee86a4SJeremy Kemp         ptr, blocking, flags, size, events, event);
9690*6fee86a4SJeremy Kemp }
9691*6fee86a4SJeremy Kemp 
9692*6fee86a4SJeremy Kemp /**
9693*6fee86a4SJeremy Kemp  * Enqueues to the default queue a command that will allow the host to
9694*6fee86a4SJeremy Kemp  * update a region of a coarse-grained SVM buffer.
9695*6fee86a4SJeremy Kemp  * This variant takes a cl::vector instance.
9696*6fee86a4SJeremy Kemp  */
9697*6fee86a4SJeremy Kemp template<typename T, class Alloc>
enqueueMapSVM(cl::vector<T,Alloc> & container,cl_bool blocking,cl_map_flags flags,const vector<Event> * events=nullptr,Event * event=nullptr)9698*6fee86a4SJeremy Kemp inline cl_int enqueueMapSVM(
9699*6fee86a4SJeremy Kemp     cl::vector<T, Alloc> &container,
9700*6fee86a4SJeremy Kemp     cl_bool blocking,
9701*6fee86a4SJeremy Kemp     cl_map_flags flags,
9702*6fee86a4SJeremy Kemp     const vector<Event>* events = nullptr,
9703*6fee86a4SJeremy Kemp     Event* event = nullptr)
9704*6fee86a4SJeremy Kemp {
9705*6fee86a4SJeremy Kemp     cl_int error;
9706*6fee86a4SJeremy Kemp     CommandQueue queue = CommandQueue::getDefault(&error);
9707*6fee86a4SJeremy Kemp     if (error != CL_SUCCESS) {
9708*6fee86a4SJeremy Kemp         return detail::errHandler(error, __ENQUEUE_MAP_SVM_ERR);
9709*6fee86a4SJeremy Kemp     }
9710*6fee86a4SJeremy Kemp 
9711*6fee86a4SJeremy Kemp     return queue.enqueueMapSVM(
9712*6fee86a4SJeremy Kemp         container, blocking, flags, events, event);
9713*6fee86a4SJeremy Kemp }
9714*6fee86a4SJeremy Kemp 
9715*6fee86a4SJeremy Kemp #endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 200
9716*6fee86a4SJeremy Kemp 
enqueueUnmapMemObject(const Memory & memory,void * mapped_ptr,const vector<Event> * events=nullptr,Event * event=nullptr)9717*6fee86a4SJeremy Kemp inline cl_int enqueueUnmapMemObject(
9718*6fee86a4SJeremy Kemp     const Memory& memory,
9719*6fee86a4SJeremy Kemp     void* mapped_ptr,
9720*6fee86a4SJeremy Kemp     const vector<Event>* events = nullptr,
9721*6fee86a4SJeremy Kemp     Event* event = nullptr)
9722*6fee86a4SJeremy Kemp {
9723*6fee86a4SJeremy Kemp     cl_int error;
9724*6fee86a4SJeremy Kemp     CommandQueue queue = CommandQueue::getDefault(&error);
9725*6fee86a4SJeremy Kemp     detail::errHandler(error, __ENQUEUE_MAP_BUFFER_ERR);
9726*6fee86a4SJeremy Kemp     if (error != CL_SUCCESS) {
9727*6fee86a4SJeremy Kemp         return error;
9728*6fee86a4SJeremy Kemp     }
9729*6fee86a4SJeremy Kemp 
9730*6fee86a4SJeremy Kemp     cl_event tmp;
9731*6fee86a4SJeremy Kemp     cl_int err = detail::errHandler(
9732*6fee86a4SJeremy Kemp         ::clEnqueueUnmapMemObject(
9733*6fee86a4SJeremy Kemp         queue(), memory(), mapped_ptr,
9734*6fee86a4SJeremy Kemp         (events != nullptr) ? (cl_uint)events->size() : 0,
9735*6fee86a4SJeremy Kemp         (events != nullptr && events->size() > 0) ? (cl_event*)&events->front() : nullptr,
9736*6fee86a4SJeremy Kemp         (event != nullptr) ? &tmp : nullptr),
9737*6fee86a4SJeremy Kemp         __ENQUEUE_UNMAP_MEM_OBJECT_ERR);
9738*6fee86a4SJeremy Kemp 
9739*6fee86a4SJeremy Kemp     if (event != nullptr && err == CL_SUCCESS)
9740*6fee86a4SJeremy Kemp         *event = tmp;
9741*6fee86a4SJeremy Kemp 
9742*6fee86a4SJeremy Kemp     return err;
9743*6fee86a4SJeremy Kemp }
9744*6fee86a4SJeremy Kemp 
9745*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 200
9746*6fee86a4SJeremy Kemp /**
9747*6fee86a4SJeremy Kemp  * Enqueues to the default queue a command that will release a coarse-grained
9748*6fee86a4SJeremy Kemp  * SVM buffer back to the OpenCL runtime.
9749*6fee86a4SJeremy Kemp  * This variant takes a raw SVM pointer.
9750*6fee86a4SJeremy Kemp  */
9751*6fee86a4SJeremy Kemp template<typename T>
enqueueUnmapSVM(T * ptr,const vector<Event> * events=nullptr,Event * event=nullptr)9752*6fee86a4SJeremy Kemp inline cl_int enqueueUnmapSVM(
9753*6fee86a4SJeremy Kemp     T* ptr,
9754*6fee86a4SJeremy Kemp     const vector<Event>* events = nullptr,
9755*6fee86a4SJeremy Kemp     Event* event = nullptr)
9756*6fee86a4SJeremy Kemp {
9757*6fee86a4SJeremy Kemp     cl_int error;
9758*6fee86a4SJeremy Kemp     CommandQueue queue = CommandQueue::getDefault(&error);
9759*6fee86a4SJeremy Kemp     if (error != CL_SUCCESS) {
9760*6fee86a4SJeremy Kemp         return detail::errHandler(error, __ENQUEUE_UNMAP_SVM_ERR);
9761*6fee86a4SJeremy Kemp     }
9762*6fee86a4SJeremy Kemp 
9763*6fee86a4SJeremy Kemp     return detail::errHandler(queue.enqueueUnmapSVM(ptr, events, event),
9764*6fee86a4SJeremy Kemp         __ENQUEUE_UNMAP_SVM_ERR);
9765*6fee86a4SJeremy Kemp 
9766*6fee86a4SJeremy Kemp }
9767*6fee86a4SJeremy Kemp 
9768*6fee86a4SJeremy Kemp /**
9769*6fee86a4SJeremy Kemp  * Enqueues to the default queue a command that will release a coarse-grained
9770*6fee86a4SJeremy Kemp  * SVM buffer back to the OpenCL runtime.
9771*6fee86a4SJeremy Kemp  * This variant takes a cl::pointer instance.
9772*6fee86a4SJeremy Kemp  */
9773*6fee86a4SJeremy Kemp template<typename T, class D>
enqueueUnmapSVM(cl::pointer<T,D> & ptr,const vector<Event> * events=nullptr,Event * event=nullptr)9774*6fee86a4SJeremy Kemp inline cl_int enqueueUnmapSVM(
9775*6fee86a4SJeremy Kemp     cl::pointer<T, D> &ptr,
9776*6fee86a4SJeremy Kemp     const vector<Event>* events = nullptr,
9777*6fee86a4SJeremy Kemp     Event* event = nullptr)
9778*6fee86a4SJeremy Kemp {
9779*6fee86a4SJeremy Kemp     cl_int error;
9780*6fee86a4SJeremy Kemp     CommandQueue queue = CommandQueue::getDefault(&error);
9781*6fee86a4SJeremy Kemp     if (error != CL_SUCCESS) {
9782*6fee86a4SJeremy Kemp         return detail::errHandler(error, __ENQUEUE_UNMAP_SVM_ERR);
9783*6fee86a4SJeremy Kemp     }
9784*6fee86a4SJeremy Kemp 
9785*6fee86a4SJeremy Kemp     return detail::errHandler(queue.enqueueUnmapSVM(ptr, events, event),
9786*6fee86a4SJeremy Kemp         __ENQUEUE_UNMAP_SVM_ERR);
9787*6fee86a4SJeremy Kemp }
9788*6fee86a4SJeremy Kemp 
9789*6fee86a4SJeremy Kemp /**
9790*6fee86a4SJeremy Kemp  * Enqueues to the default queue a command that will release a coarse-grained
9791*6fee86a4SJeremy Kemp  * SVM buffer back to the OpenCL runtime.
9792*6fee86a4SJeremy Kemp  * This variant takes a cl::vector instance.
9793*6fee86a4SJeremy Kemp  */
9794*6fee86a4SJeremy Kemp template<typename T, class Alloc>
enqueueUnmapSVM(cl::vector<T,Alloc> & container,const vector<Event> * events=nullptr,Event * event=nullptr)9795*6fee86a4SJeremy Kemp inline cl_int enqueueUnmapSVM(
9796*6fee86a4SJeremy Kemp     cl::vector<T, Alloc> &container,
9797*6fee86a4SJeremy Kemp     const vector<Event>* events = nullptr,
9798*6fee86a4SJeremy Kemp     Event* event = nullptr)
9799*6fee86a4SJeremy Kemp {
9800*6fee86a4SJeremy Kemp     cl_int error;
9801*6fee86a4SJeremy Kemp     CommandQueue queue = CommandQueue::getDefault(&error);
9802*6fee86a4SJeremy Kemp     if (error != CL_SUCCESS) {
9803*6fee86a4SJeremy Kemp         return detail::errHandler(error, __ENQUEUE_UNMAP_SVM_ERR);
9804*6fee86a4SJeremy Kemp     }
9805*6fee86a4SJeremy Kemp 
9806*6fee86a4SJeremy Kemp     return detail::errHandler(queue.enqueueUnmapSVM(container, events, event),
9807*6fee86a4SJeremy Kemp         __ENQUEUE_UNMAP_SVM_ERR);
9808*6fee86a4SJeremy Kemp }
9809*6fee86a4SJeremy Kemp 
9810*6fee86a4SJeremy Kemp #endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 200
9811*6fee86a4SJeremy Kemp 
enqueueCopyBuffer(const Buffer & src,const Buffer & dst,size_type src_offset,size_type dst_offset,size_type size,const vector<Event> * events=nullptr,Event * event=nullptr)9812*6fee86a4SJeremy Kemp inline cl_int enqueueCopyBuffer(
9813*6fee86a4SJeremy Kemp         const Buffer& src,
9814*6fee86a4SJeremy Kemp         const Buffer& dst,
9815*6fee86a4SJeremy Kemp         size_type src_offset,
9816*6fee86a4SJeremy Kemp         size_type dst_offset,
9817*6fee86a4SJeremy Kemp         size_type size,
9818*6fee86a4SJeremy Kemp         const vector<Event>* events = nullptr,
9819*6fee86a4SJeremy Kemp         Event* event = nullptr)
9820*6fee86a4SJeremy Kemp {
9821*6fee86a4SJeremy Kemp     cl_int error;
9822*6fee86a4SJeremy Kemp     CommandQueue queue = CommandQueue::getDefault(&error);
9823*6fee86a4SJeremy Kemp 
9824*6fee86a4SJeremy Kemp     if (error != CL_SUCCESS) {
9825*6fee86a4SJeremy Kemp         return error;
9826*6fee86a4SJeremy Kemp     }
9827*6fee86a4SJeremy Kemp 
9828*6fee86a4SJeremy Kemp     return queue.enqueueCopyBuffer(src, dst, src_offset, dst_offset, size, events, event);
9829*6fee86a4SJeremy Kemp }
9830*6fee86a4SJeremy Kemp 
9831*6fee86a4SJeremy Kemp /**
9832*6fee86a4SJeremy Kemp  * Blocking copy operation between iterators and a buffer.
9833*6fee86a4SJeremy Kemp  * Host to Device.
9834*6fee86a4SJeremy Kemp  * Uses default command queue.
9835*6fee86a4SJeremy Kemp  */
9836*6fee86a4SJeremy Kemp template< typename IteratorType >
copy(IteratorType startIterator,IteratorType endIterator,cl::Buffer & buffer)9837*6fee86a4SJeremy Kemp inline cl_int copy( IteratorType startIterator, IteratorType endIterator, cl::Buffer &buffer )
9838*6fee86a4SJeremy Kemp {
9839*6fee86a4SJeremy Kemp     cl_int error;
9840*6fee86a4SJeremy Kemp     CommandQueue queue = CommandQueue::getDefault(&error);
9841*6fee86a4SJeremy Kemp     if (error != CL_SUCCESS)
9842*6fee86a4SJeremy Kemp         return error;
9843*6fee86a4SJeremy Kemp 
9844*6fee86a4SJeremy Kemp     return cl::copy(queue, startIterator, endIterator, buffer);
9845*6fee86a4SJeremy Kemp }
9846*6fee86a4SJeremy Kemp 
9847*6fee86a4SJeremy Kemp /**
9848*6fee86a4SJeremy Kemp  * Blocking copy operation between iterators and a buffer.
9849*6fee86a4SJeremy Kemp  * Device to Host.
9850*6fee86a4SJeremy Kemp  * Uses default command queue.
9851*6fee86a4SJeremy Kemp  */
9852*6fee86a4SJeremy Kemp template< typename IteratorType >
copy(const cl::Buffer & buffer,IteratorType startIterator,IteratorType endIterator)9853*6fee86a4SJeremy Kemp inline cl_int copy( const cl::Buffer &buffer, IteratorType startIterator, IteratorType endIterator )
9854*6fee86a4SJeremy Kemp {
9855*6fee86a4SJeremy Kemp     cl_int error;
9856*6fee86a4SJeremy Kemp     CommandQueue queue = CommandQueue::getDefault(&error);
9857*6fee86a4SJeremy Kemp     if (error != CL_SUCCESS)
9858*6fee86a4SJeremy Kemp         return error;
9859*6fee86a4SJeremy Kemp 
9860*6fee86a4SJeremy Kemp     return cl::copy(queue, buffer, startIterator, endIterator);
9861*6fee86a4SJeremy Kemp }
9862*6fee86a4SJeremy Kemp 
9863*6fee86a4SJeremy Kemp /**
9864*6fee86a4SJeremy Kemp  * Blocking copy operation between iterators and a buffer.
9865*6fee86a4SJeremy Kemp  * Host to Device.
9866*6fee86a4SJeremy Kemp  * Uses specified queue.
9867*6fee86a4SJeremy Kemp  */
9868*6fee86a4SJeremy Kemp template< typename IteratorType >
copy(const CommandQueue & queue,IteratorType startIterator,IteratorType endIterator,cl::Buffer & buffer)9869*6fee86a4SJeremy Kemp inline cl_int copy( const CommandQueue &queue, IteratorType startIterator, IteratorType endIterator, cl::Buffer &buffer )
9870*6fee86a4SJeremy Kemp {
9871*6fee86a4SJeremy Kemp     typedef typename std::iterator_traits<IteratorType>::value_type DataType;
9872*6fee86a4SJeremy Kemp     cl_int error;
9873*6fee86a4SJeremy Kemp 
9874*6fee86a4SJeremy Kemp     size_type length = endIterator-startIterator;
9875*6fee86a4SJeremy Kemp     size_type byteLength = length*sizeof(DataType);
9876*6fee86a4SJeremy Kemp 
9877*6fee86a4SJeremy Kemp     DataType *pointer =
9878*6fee86a4SJeremy Kemp         static_cast<DataType*>(queue.enqueueMapBuffer(buffer, CL_TRUE, CL_MAP_WRITE, 0, byteLength, 0, 0, &error));
9879*6fee86a4SJeremy Kemp     // if exceptions enabled, enqueueMapBuffer will throw
9880*6fee86a4SJeremy Kemp     if( error != CL_SUCCESS ) {
9881*6fee86a4SJeremy Kemp         return error;
9882*6fee86a4SJeremy Kemp     }
9883*6fee86a4SJeremy Kemp #if defined(_MSC_VER)
9884*6fee86a4SJeremy Kemp     std::copy(
9885*6fee86a4SJeremy Kemp         startIterator,
9886*6fee86a4SJeremy Kemp         endIterator,
9887*6fee86a4SJeremy Kemp         stdext::checked_array_iterator<DataType*>(
9888*6fee86a4SJeremy Kemp             pointer, length));
9889*6fee86a4SJeremy Kemp #else
9890*6fee86a4SJeremy Kemp     std::copy(startIterator, endIterator, pointer);
9891*6fee86a4SJeremy Kemp #endif
9892*6fee86a4SJeremy Kemp     Event endEvent;
9893*6fee86a4SJeremy Kemp     error = queue.enqueueUnmapMemObject(buffer, pointer, 0, &endEvent);
9894*6fee86a4SJeremy Kemp     // if exceptions enabled, enqueueUnmapMemObject will throw
9895*6fee86a4SJeremy Kemp     if( error != CL_SUCCESS ) {
9896*6fee86a4SJeremy Kemp         return error;
9897*6fee86a4SJeremy Kemp     }
9898*6fee86a4SJeremy Kemp     endEvent.wait();
9899*6fee86a4SJeremy Kemp     return CL_SUCCESS;
9900*6fee86a4SJeremy Kemp }
9901*6fee86a4SJeremy Kemp 
9902*6fee86a4SJeremy Kemp /**
9903*6fee86a4SJeremy Kemp  * Blocking copy operation between iterators and a buffer.
9904*6fee86a4SJeremy Kemp  * Device to Host.
9905*6fee86a4SJeremy Kemp  * Uses specified queue.
9906*6fee86a4SJeremy Kemp  */
9907*6fee86a4SJeremy Kemp template< typename IteratorType >
copy(const CommandQueue & queue,const cl::Buffer & buffer,IteratorType startIterator,IteratorType endIterator)9908*6fee86a4SJeremy Kemp inline cl_int copy( const CommandQueue &queue, const cl::Buffer &buffer, IteratorType startIterator, IteratorType endIterator )
9909*6fee86a4SJeremy Kemp {
9910*6fee86a4SJeremy Kemp     typedef typename std::iterator_traits<IteratorType>::value_type DataType;
9911*6fee86a4SJeremy Kemp     cl_int error;
9912*6fee86a4SJeremy Kemp 
9913*6fee86a4SJeremy Kemp     size_type length = endIterator-startIterator;
9914*6fee86a4SJeremy Kemp     size_type byteLength = length*sizeof(DataType);
9915*6fee86a4SJeremy Kemp 
9916*6fee86a4SJeremy Kemp     DataType *pointer =
9917*6fee86a4SJeremy Kemp         static_cast<DataType*>(queue.enqueueMapBuffer(buffer, CL_TRUE, CL_MAP_READ, 0, byteLength, 0, 0, &error));
9918*6fee86a4SJeremy Kemp     // if exceptions enabled, enqueueMapBuffer will throw
9919*6fee86a4SJeremy Kemp     if( error != CL_SUCCESS ) {
9920*6fee86a4SJeremy Kemp         return error;
9921*6fee86a4SJeremy Kemp     }
9922*6fee86a4SJeremy Kemp     std::copy(pointer, pointer + length, startIterator);
9923*6fee86a4SJeremy Kemp     Event endEvent;
9924*6fee86a4SJeremy Kemp     error = queue.enqueueUnmapMemObject(buffer, pointer, 0, &endEvent);
9925*6fee86a4SJeremy Kemp     // if exceptions enabled, enqueueUnmapMemObject will throw
9926*6fee86a4SJeremy Kemp     if( error != CL_SUCCESS ) {
9927*6fee86a4SJeremy Kemp         return error;
9928*6fee86a4SJeremy Kemp     }
9929*6fee86a4SJeremy Kemp     endEvent.wait();
9930*6fee86a4SJeremy Kemp     return CL_SUCCESS;
9931*6fee86a4SJeremy Kemp }
9932*6fee86a4SJeremy Kemp 
9933*6fee86a4SJeremy Kemp 
9934*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 200
9935*6fee86a4SJeremy Kemp /**
9936*6fee86a4SJeremy Kemp  * Blocking SVM map operation - performs a blocking map underneath.
9937*6fee86a4SJeremy Kemp  */
9938*6fee86a4SJeremy Kemp template<typename T, class Alloc>
mapSVM(cl::vector<T,Alloc> & container)9939*6fee86a4SJeremy Kemp inline cl_int mapSVM(cl::vector<T, Alloc> &container)
9940*6fee86a4SJeremy Kemp {
9941*6fee86a4SJeremy Kemp     return enqueueMapSVM(container, CL_TRUE, CL_MAP_READ | CL_MAP_WRITE);
9942*6fee86a4SJeremy Kemp }
9943*6fee86a4SJeremy Kemp 
9944*6fee86a4SJeremy Kemp /**
9945*6fee86a4SJeremy Kemp * Blocking SVM map operation - performs a blocking map underneath.
9946*6fee86a4SJeremy Kemp */
9947*6fee86a4SJeremy Kemp template<typename T, class Alloc>
unmapSVM(cl::vector<T,Alloc> & container)9948*6fee86a4SJeremy Kemp inline cl_int unmapSVM(cl::vector<T, Alloc> &container)
9949*6fee86a4SJeremy Kemp {
9950*6fee86a4SJeremy Kemp     return enqueueUnmapSVM(container);
9951*6fee86a4SJeremy Kemp }
9952*6fee86a4SJeremy Kemp 
9953*6fee86a4SJeremy Kemp #endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 200
9954*6fee86a4SJeremy Kemp 
9955*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 110
enqueueReadBufferRect(const Buffer & buffer,cl_bool blocking,const array<size_type,3> & buffer_offset,const array<size_type,3> & host_offset,const array<size_type,3> & region,size_type buffer_row_pitch,size_type buffer_slice_pitch,size_type host_row_pitch,size_type host_slice_pitch,void * ptr,const vector<Event> * events=nullptr,Event * event=nullptr)9956*6fee86a4SJeremy Kemp inline cl_int enqueueReadBufferRect(
9957*6fee86a4SJeremy Kemp     const Buffer& buffer,
9958*6fee86a4SJeremy Kemp     cl_bool blocking,
9959*6fee86a4SJeremy Kemp     const array<size_type, 3>& buffer_offset,
9960*6fee86a4SJeremy Kemp     const array<size_type, 3>& host_offset,
9961*6fee86a4SJeremy Kemp     const array<size_type, 3>& region,
9962*6fee86a4SJeremy Kemp     size_type buffer_row_pitch,
9963*6fee86a4SJeremy Kemp     size_type buffer_slice_pitch,
9964*6fee86a4SJeremy Kemp     size_type host_row_pitch,
9965*6fee86a4SJeremy Kemp     size_type host_slice_pitch,
9966*6fee86a4SJeremy Kemp     void *ptr,
9967*6fee86a4SJeremy Kemp     const vector<Event>* events = nullptr,
9968*6fee86a4SJeremy Kemp     Event* event = nullptr)
9969*6fee86a4SJeremy Kemp {
9970*6fee86a4SJeremy Kemp     cl_int error;
9971*6fee86a4SJeremy Kemp     CommandQueue queue = CommandQueue::getDefault(&error);
9972*6fee86a4SJeremy Kemp 
9973*6fee86a4SJeremy Kemp     if (error != CL_SUCCESS) {
9974*6fee86a4SJeremy Kemp         return error;
9975*6fee86a4SJeremy Kemp     }
9976*6fee86a4SJeremy Kemp 
9977*6fee86a4SJeremy Kemp     return queue.enqueueReadBufferRect(
9978*6fee86a4SJeremy Kemp         buffer,
9979*6fee86a4SJeremy Kemp         blocking,
9980*6fee86a4SJeremy Kemp         buffer_offset,
9981*6fee86a4SJeremy Kemp         host_offset,
9982*6fee86a4SJeremy Kemp         region,
9983*6fee86a4SJeremy Kemp         buffer_row_pitch,
9984*6fee86a4SJeremy Kemp         buffer_slice_pitch,
9985*6fee86a4SJeremy Kemp         host_row_pitch,
9986*6fee86a4SJeremy Kemp         host_slice_pitch,
9987*6fee86a4SJeremy Kemp         ptr,
9988*6fee86a4SJeremy Kemp         events,
9989*6fee86a4SJeremy Kemp         event);
9990*6fee86a4SJeremy Kemp }
9991*6fee86a4SJeremy Kemp 
enqueueReadBufferRect(const Buffer & buffer,cl_bool blocking,const array<size_type,2> & buffer_offset,const array<size_type,2> & host_offset,const array<size_type,2> & region,size_type buffer_row_pitch,size_type buffer_slice_pitch,size_type host_row_pitch,size_type host_slice_pitch,void * ptr,const vector<Event> * events=nullptr,Event * event=nullptr)9992*6fee86a4SJeremy Kemp inline cl_int enqueueReadBufferRect(
9993*6fee86a4SJeremy Kemp     const Buffer& buffer,
9994*6fee86a4SJeremy Kemp     cl_bool blocking,
9995*6fee86a4SJeremy Kemp     const array<size_type, 2>& buffer_offset,
9996*6fee86a4SJeremy Kemp     const array<size_type, 2>& host_offset,
9997*6fee86a4SJeremy Kemp     const array<size_type, 2>& region,
9998*6fee86a4SJeremy Kemp     size_type buffer_row_pitch,
9999*6fee86a4SJeremy Kemp     size_type buffer_slice_pitch,
10000*6fee86a4SJeremy Kemp     size_type host_row_pitch,
10001*6fee86a4SJeremy Kemp     size_type host_slice_pitch,
10002*6fee86a4SJeremy Kemp     void* ptr,
10003*6fee86a4SJeremy Kemp     const vector<Event>* events = nullptr,
10004*6fee86a4SJeremy Kemp     Event* event = nullptr)
10005*6fee86a4SJeremy Kemp {
10006*6fee86a4SJeremy Kemp     return enqueueReadBufferRect(
10007*6fee86a4SJeremy Kemp         buffer,
10008*6fee86a4SJeremy Kemp         blocking,
10009*6fee86a4SJeremy Kemp         { buffer_offset[0], buffer_offset[1], 0 },
10010*6fee86a4SJeremy Kemp         { host_offset[0], host_offset[1], 0 },
10011*6fee86a4SJeremy Kemp         { region[0], region[1], 1 },
10012*6fee86a4SJeremy Kemp         buffer_row_pitch,
10013*6fee86a4SJeremy Kemp         buffer_slice_pitch,
10014*6fee86a4SJeremy Kemp         host_row_pitch,
10015*6fee86a4SJeremy Kemp         host_slice_pitch,
10016*6fee86a4SJeremy Kemp         ptr,
10017*6fee86a4SJeremy Kemp         events,
10018*6fee86a4SJeremy Kemp         event);
10019*6fee86a4SJeremy Kemp }
10020*6fee86a4SJeremy Kemp 
enqueueWriteBufferRect(const Buffer & buffer,cl_bool blocking,const array<size_type,3> & buffer_offset,const array<size_type,3> & host_offset,const array<size_type,3> & region,size_type buffer_row_pitch,size_type buffer_slice_pitch,size_type host_row_pitch,size_type host_slice_pitch,const void * ptr,const vector<Event> * events=nullptr,Event * event=nullptr)10021*6fee86a4SJeremy Kemp inline cl_int enqueueWriteBufferRect(
10022*6fee86a4SJeremy Kemp     const Buffer& buffer,
10023*6fee86a4SJeremy Kemp     cl_bool blocking,
10024*6fee86a4SJeremy Kemp     const array<size_type, 3>& buffer_offset,
10025*6fee86a4SJeremy Kemp     const array<size_type, 3>& host_offset,
10026*6fee86a4SJeremy Kemp     const array<size_type, 3>& region,
10027*6fee86a4SJeremy Kemp     size_type buffer_row_pitch,
10028*6fee86a4SJeremy Kemp     size_type buffer_slice_pitch,
10029*6fee86a4SJeremy Kemp     size_type host_row_pitch,
10030*6fee86a4SJeremy Kemp     size_type host_slice_pitch,
10031*6fee86a4SJeremy Kemp     const void *ptr,
10032*6fee86a4SJeremy Kemp     const vector<Event>* events = nullptr,
10033*6fee86a4SJeremy Kemp     Event* event = nullptr)
10034*6fee86a4SJeremy Kemp {
10035*6fee86a4SJeremy Kemp     cl_int error;
10036*6fee86a4SJeremy Kemp     CommandQueue queue = CommandQueue::getDefault(&error);
10037*6fee86a4SJeremy Kemp 
10038*6fee86a4SJeremy Kemp     if (error != CL_SUCCESS) {
10039*6fee86a4SJeremy Kemp         return error;
10040*6fee86a4SJeremy Kemp     }
10041*6fee86a4SJeremy Kemp 
10042*6fee86a4SJeremy Kemp     return queue.enqueueWriteBufferRect(
10043*6fee86a4SJeremy Kemp         buffer,
10044*6fee86a4SJeremy Kemp         blocking,
10045*6fee86a4SJeremy Kemp         buffer_offset,
10046*6fee86a4SJeremy Kemp         host_offset,
10047*6fee86a4SJeremy Kemp         region,
10048*6fee86a4SJeremy Kemp         buffer_row_pitch,
10049*6fee86a4SJeremy Kemp         buffer_slice_pitch,
10050*6fee86a4SJeremy Kemp         host_row_pitch,
10051*6fee86a4SJeremy Kemp         host_slice_pitch,
10052*6fee86a4SJeremy Kemp         ptr,
10053*6fee86a4SJeremy Kemp         events,
10054*6fee86a4SJeremy Kemp         event);
10055*6fee86a4SJeremy Kemp }
10056*6fee86a4SJeremy Kemp 
enqueueWriteBufferRect(const Buffer & buffer,cl_bool blocking,const array<size_type,2> & buffer_offset,const array<size_type,2> & host_offset,const array<size_type,2> & region,size_type buffer_row_pitch,size_type buffer_slice_pitch,size_type host_row_pitch,size_type host_slice_pitch,const void * ptr,const vector<Event> * events=nullptr,Event * event=nullptr)10057*6fee86a4SJeremy Kemp inline cl_int enqueueWriteBufferRect(
10058*6fee86a4SJeremy Kemp     const Buffer& buffer,
10059*6fee86a4SJeremy Kemp     cl_bool blocking,
10060*6fee86a4SJeremy Kemp     const array<size_type, 2>& buffer_offset,
10061*6fee86a4SJeremy Kemp     const array<size_type, 2>& host_offset,
10062*6fee86a4SJeremy Kemp     const array<size_type, 2>& region,
10063*6fee86a4SJeremy Kemp     size_type buffer_row_pitch,
10064*6fee86a4SJeremy Kemp     size_type buffer_slice_pitch,
10065*6fee86a4SJeremy Kemp     size_type host_row_pitch,
10066*6fee86a4SJeremy Kemp     size_type host_slice_pitch,
10067*6fee86a4SJeremy Kemp     const void* ptr,
10068*6fee86a4SJeremy Kemp     const vector<Event>* events = nullptr,
10069*6fee86a4SJeremy Kemp     Event* event = nullptr)
10070*6fee86a4SJeremy Kemp {
10071*6fee86a4SJeremy Kemp     return enqueueWriteBufferRect(
10072*6fee86a4SJeremy Kemp         buffer,
10073*6fee86a4SJeremy Kemp         blocking,
10074*6fee86a4SJeremy Kemp         { buffer_offset[0], buffer_offset[1], 0 },
10075*6fee86a4SJeremy Kemp         { host_offset[0], host_offset[1], 0 },
10076*6fee86a4SJeremy Kemp         { region[0], region[1], 1 },
10077*6fee86a4SJeremy Kemp         buffer_row_pitch,
10078*6fee86a4SJeremy Kemp         buffer_slice_pitch,
10079*6fee86a4SJeremy Kemp         host_row_pitch,
10080*6fee86a4SJeremy Kemp         host_slice_pitch,
10081*6fee86a4SJeremy Kemp         ptr,
10082*6fee86a4SJeremy Kemp         events,
10083*6fee86a4SJeremy Kemp         event);
10084*6fee86a4SJeremy Kemp }
10085*6fee86a4SJeremy Kemp 
enqueueCopyBufferRect(const Buffer & src,const Buffer & dst,const array<size_type,3> & src_origin,const array<size_type,3> & dst_origin,const array<size_type,3> & region,size_type src_row_pitch,size_type src_slice_pitch,size_type dst_row_pitch,size_type dst_slice_pitch,const vector<Event> * events=nullptr,Event * event=nullptr)10086*6fee86a4SJeremy Kemp inline cl_int enqueueCopyBufferRect(
10087*6fee86a4SJeremy Kemp     const Buffer& src,
10088*6fee86a4SJeremy Kemp     const Buffer& dst,
10089*6fee86a4SJeremy Kemp     const array<size_type, 3>& src_origin,
10090*6fee86a4SJeremy Kemp     const array<size_type, 3>& dst_origin,
10091*6fee86a4SJeremy Kemp     const array<size_type, 3>& region,
10092*6fee86a4SJeremy Kemp     size_type src_row_pitch,
10093*6fee86a4SJeremy Kemp     size_type src_slice_pitch,
10094*6fee86a4SJeremy Kemp     size_type dst_row_pitch,
10095*6fee86a4SJeremy Kemp     size_type dst_slice_pitch,
10096*6fee86a4SJeremy Kemp     const vector<Event>* events = nullptr,
10097*6fee86a4SJeremy Kemp     Event* event = nullptr)
10098*6fee86a4SJeremy Kemp {
10099*6fee86a4SJeremy Kemp     cl_int error;
10100*6fee86a4SJeremy Kemp     CommandQueue queue = CommandQueue::getDefault(&error);
10101*6fee86a4SJeremy Kemp 
10102*6fee86a4SJeremy Kemp     if (error != CL_SUCCESS) {
10103*6fee86a4SJeremy Kemp         return error;
10104*6fee86a4SJeremy Kemp     }
10105*6fee86a4SJeremy Kemp 
10106*6fee86a4SJeremy Kemp     return queue.enqueueCopyBufferRect(
10107*6fee86a4SJeremy Kemp         src,
10108*6fee86a4SJeremy Kemp         dst,
10109*6fee86a4SJeremy Kemp         src_origin,
10110*6fee86a4SJeremy Kemp         dst_origin,
10111*6fee86a4SJeremy Kemp         region,
10112*6fee86a4SJeremy Kemp         src_row_pitch,
10113*6fee86a4SJeremy Kemp         src_slice_pitch,
10114*6fee86a4SJeremy Kemp         dst_row_pitch,
10115*6fee86a4SJeremy Kemp         dst_slice_pitch,
10116*6fee86a4SJeremy Kemp         events,
10117*6fee86a4SJeremy Kemp         event);
10118*6fee86a4SJeremy Kemp }
10119*6fee86a4SJeremy Kemp 
enqueueCopyBufferRect(const Buffer & src,const Buffer & dst,const array<size_type,2> & src_origin,const array<size_type,2> & dst_origin,const array<size_type,2> & region,size_type src_row_pitch,size_type src_slice_pitch,size_type dst_row_pitch,size_type dst_slice_pitch,const vector<Event> * events=nullptr,Event * event=nullptr)10120*6fee86a4SJeremy Kemp inline cl_int enqueueCopyBufferRect(
10121*6fee86a4SJeremy Kemp     const Buffer& src,
10122*6fee86a4SJeremy Kemp     const Buffer& dst,
10123*6fee86a4SJeremy Kemp     const array<size_type, 2>& src_origin,
10124*6fee86a4SJeremy Kemp     const array<size_type, 2>& dst_origin,
10125*6fee86a4SJeremy Kemp     const array<size_type, 2>& region,
10126*6fee86a4SJeremy Kemp     size_type src_row_pitch,
10127*6fee86a4SJeremy Kemp     size_type src_slice_pitch,
10128*6fee86a4SJeremy Kemp     size_type dst_row_pitch,
10129*6fee86a4SJeremy Kemp     size_type dst_slice_pitch,
10130*6fee86a4SJeremy Kemp     const vector<Event>* events = nullptr,
10131*6fee86a4SJeremy Kemp     Event* event = nullptr)
10132*6fee86a4SJeremy Kemp {
10133*6fee86a4SJeremy Kemp     return enqueueCopyBufferRect(
10134*6fee86a4SJeremy Kemp         src,
10135*6fee86a4SJeremy Kemp         dst,
10136*6fee86a4SJeremy Kemp         { src_origin[0], src_origin[1], 0 },
10137*6fee86a4SJeremy Kemp         { dst_origin[0], dst_origin[1], 0 },
10138*6fee86a4SJeremy Kemp         { region[0], region[1], 1 },
10139*6fee86a4SJeremy Kemp         src_row_pitch,
10140*6fee86a4SJeremy Kemp         src_slice_pitch,
10141*6fee86a4SJeremy Kemp         dst_row_pitch,
10142*6fee86a4SJeremy Kemp         dst_slice_pitch,
10143*6fee86a4SJeremy Kemp         events,
10144*6fee86a4SJeremy Kemp         event);
10145*6fee86a4SJeremy Kemp }
10146*6fee86a4SJeremy Kemp #endif // CL_HPP_TARGET_OPENCL_VERSION >= 110
10147*6fee86a4SJeremy Kemp 
enqueueReadImage(const Image & image,cl_bool blocking,const array<size_type,3> & origin,const array<size_type,3> & region,size_type row_pitch,size_type slice_pitch,void * ptr,const vector<Event> * events=nullptr,Event * event=nullptr)10148*6fee86a4SJeremy Kemp inline cl_int enqueueReadImage(
10149*6fee86a4SJeremy Kemp     const Image& image,
10150*6fee86a4SJeremy Kemp     cl_bool blocking,
10151*6fee86a4SJeremy Kemp     const array<size_type, 3>& origin,
10152*6fee86a4SJeremy Kemp     const array<size_type, 3>& region,
10153*6fee86a4SJeremy Kemp     size_type row_pitch,
10154*6fee86a4SJeremy Kemp     size_type slice_pitch,
10155*6fee86a4SJeremy Kemp     void* ptr,
10156*6fee86a4SJeremy Kemp     const vector<Event>* events = nullptr,
10157*6fee86a4SJeremy Kemp     Event* event = nullptr)
10158*6fee86a4SJeremy Kemp {
10159*6fee86a4SJeremy Kemp     cl_int error;
10160*6fee86a4SJeremy Kemp     CommandQueue queue = CommandQueue::getDefault(&error);
10161*6fee86a4SJeremy Kemp 
10162*6fee86a4SJeremy Kemp     if (error != CL_SUCCESS) {
10163*6fee86a4SJeremy Kemp         return error;
10164*6fee86a4SJeremy Kemp     }
10165*6fee86a4SJeremy Kemp 
10166*6fee86a4SJeremy Kemp     return queue.enqueueReadImage(
10167*6fee86a4SJeremy Kemp         image,
10168*6fee86a4SJeremy Kemp         blocking,
10169*6fee86a4SJeremy Kemp         origin,
10170*6fee86a4SJeremy Kemp         region,
10171*6fee86a4SJeremy Kemp         row_pitch,
10172*6fee86a4SJeremy Kemp         slice_pitch,
10173*6fee86a4SJeremy Kemp         ptr,
10174*6fee86a4SJeremy Kemp         events,
10175*6fee86a4SJeremy Kemp         event);
10176*6fee86a4SJeremy Kemp }
10177*6fee86a4SJeremy Kemp 
enqueueReadImage(const Image & image,cl_bool blocking,const array<size_type,2> & origin,const array<size_type,2> & region,size_type row_pitch,size_type slice_pitch,void * ptr,const vector<Event> * events=nullptr,Event * event=nullptr)10178*6fee86a4SJeremy Kemp inline cl_int enqueueReadImage(
10179*6fee86a4SJeremy Kemp     const Image& image,
10180*6fee86a4SJeremy Kemp     cl_bool blocking,
10181*6fee86a4SJeremy Kemp     const array<size_type, 2>& origin,
10182*6fee86a4SJeremy Kemp     const array<size_type, 2>& region,
10183*6fee86a4SJeremy Kemp     size_type row_pitch,
10184*6fee86a4SJeremy Kemp     size_type slice_pitch,
10185*6fee86a4SJeremy Kemp     void* ptr,
10186*6fee86a4SJeremy Kemp     const vector<Event>* events = nullptr,
10187*6fee86a4SJeremy Kemp     Event* event = nullptr)
10188*6fee86a4SJeremy Kemp {
10189*6fee86a4SJeremy Kemp     return enqueueReadImage(
10190*6fee86a4SJeremy Kemp         image,
10191*6fee86a4SJeremy Kemp         blocking,
10192*6fee86a4SJeremy Kemp         { origin[0], origin[1], 0 },
10193*6fee86a4SJeremy Kemp         { region[0], region[1], 1 },
10194*6fee86a4SJeremy Kemp         row_pitch,
10195*6fee86a4SJeremy Kemp         slice_pitch,
10196*6fee86a4SJeremy Kemp         ptr,
10197*6fee86a4SJeremy Kemp         events,
10198*6fee86a4SJeremy Kemp         event);
10199*6fee86a4SJeremy Kemp }
10200*6fee86a4SJeremy Kemp 
enqueueWriteImage(const Image & image,cl_bool blocking,const array<size_type,3> & origin,const array<size_type,3> & region,size_type row_pitch,size_type slice_pitch,const void * ptr,const vector<Event> * events=nullptr,Event * event=nullptr)10201*6fee86a4SJeremy Kemp inline cl_int enqueueWriteImage(
10202*6fee86a4SJeremy Kemp     const Image& image,
10203*6fee86a4SJeremy Kemp     cl_bool blocking,
10204*6fee86a4SJeremy Kemp     const array<size_type, 3>& origin,
10205*6fee86a4SJeremy Kemp     const array<size_type, 3>& region,
10206*6fee86a4SJeremy Kemp     size_type row_pitch,
10207*6fee86a4SJeremy Kemp     size_type slice_pitch,
10208*6fee86a4SJeremy Kemp     const void* ptr,
10209*6fee86a4SJeremy Kemp     const vector<Event>* events = nullptr,
10210*6fee86a4SJeremy Kemp     Event* event = nullptr)
10211*6fee86a4SJeremy Kemp {
10212*6fee86a4SJeremy Kemp     cl_int error;
10213*6fee86a4SJeremy Kemp     CommandQueue queue = CommandQueue::getDefault(&error);
10214*6fee86a4SJeremy Kemp 
10215*6fee86a4SJeremy Kemp     if (error != CL_SUCCESS) {
10216*6fee86a4SJeremy Kemp         return error;
10217*6fee86a4SJeremy Kemp     }
10218*6fee86a4SJeremy Kemp 
10219*6fee86a4SJeremy Kemp     return queue.enqueueWriteImage(
10220*6fee86a4SJeremy Kemp         image,
10221*6fee86a4SJeremy Kemp         blocking,
10222*6fee86a4SJeremy Kemp         origin,
10223*6fee86a4SJeremy Kemp         region,
10224*6fee86a4SJeremy Kemp         row_pitch,
10225*6fee86a4SJeremy Kemp         slice_pitch,
10226*6fee86a4SJeremy Kemp         ptr,
10227*6fee86a4SJeremy Kemp         events,
10228*6fee86a4SJeremy Kemp         event);
10229*6fee86a4SJeremy Kemp }
10230*6fee86a4SJeremy Kemp 
enqueueWriteImage(const Image & image,cl_bool blocking,const array<size_type,2> & origin,const array<size_type,2> & region,size_type row_pitch,size_type slice_pitch,const void * ptr,const vector<Event> * events=nullptr,Event * event=nullptr)10231*6fee86a4SJeremy Kemp inline cl_int enqueueWriteImage(
10232*6fee86a4SJeremy Kemp     const Image& image,
10233*6fee86a4SJeremy Kemp     cl_bool blocking,
10234*6fee86a4SJeremy Kemp     const array<size_type, 2>& origin,
10235*6fee86a4SJeremy Kemp     const array<size_type, 2>& region,
10236*6fee86a4SJeremy Kemp     size_type row_pitch,
10237*6fee86a4SJeremy Kemp     size_type slice_pitch,
10238*6fee86a4SJeremy Kemp     const void* ptr,
10239*6fee86a4SJeremy Kemp     const vector<Event>* events = nullptr,
10240*6fee86a4SJeremy Kemp     Event* event = nullptr)
10241*6fee86a4SJeremy Kemp {
10242*6fee86a4SJeremy Kemp     return enqueueWriteImage(
10243*6fee86a4SJeremy Kemp         image,
10244*6fee86a4SJeremy Kemp         blocking,
10245*6fee86a4SJeremy Kemp         { origin[0], origin[1], 0 },
10246*6fee86a4SJeremy Kemp         { region[0], region[1], 1 },
10247*6fee86a4SJeremy Kemp         row_pitch,
10248*6fee86a4SJeremy Kemp         slice_pitch,
10249*6fee86a4SJeremy Kemp         ptr,
10250*6fee86a4SJeremy Kemp         events,
10251*6fee86a4SJeremy Kemp         event);
10252*6fee86a4SJeremy Kemp }
10253*6fee86a4SJeremy Kemp 
enqueueCopyImage(const Image & src,const Image & dst,const array<size_type,3> & src_origin,const array<size_type,3> & dst_origin,const array<size_type,3> & region,const vector<Event> * events=nullptr,Event * event=nullptr)10254*6fee86a4SJeremy Kemp inline cl_int enqueueCopyImage(
10255*6fee86a4SJeremy Kemp     const Image& src,
10256*6fee86a4SJeremy Kemp     const Image& dst,
10257*6fee86a4SJeremy Kemp     const array<size_type, 3>& src_origin,
10258*6fee86a4SJeremy Kemp     const array<size_type, 3>& dst_origin,
10259*6fee86a4SJeremy Kemp     const array<size_type, 3>& region,
10260*6fee86a4SJeremy Kemp     const vector<Event>* events = nullptr,
10261*6fee86a4SJeremy Kemp     Event* event = nullptr)
10262*6fee86a4SJeremy Kemp {
10263*6fee86a4SJeremy Kemp     cl_int error;
10264*6fee86a4SJeremy Kemp     CommandQueue queue = CommandQueue::getDefault(&error);
10265*6fee86a4SJeremy Kemp 
10266*6fee86a4SJeremy Kemp     if (error != CL_SUCCESS) {
10267*6fee86a4SJeremy Kemp         return error;
10268*6fee86a4SJeremy Kemp     }
10269*6fee86a4SJeremy Kemp 
10270*6fee86a4SJeremy Kemp     return queue.enqueueCopyImage(
10271*6fee86a4SJeremy Kemp         src,
10272*6fee86a4SJeremy Kemp         dst,
10273*6fee86a4SJeremy Kemp         src_origin,
10274*6fee86a4SJeremy Kemp         dst_origin,
10275*6fee86a4SJeremy Kemp         region,
10276*6fee86a4SJeremy Kemp         events,
10277*6fee86a4SJeremy Kemp         event);
10278*6fee86a4SJeremy Kemp }
10279*6fee86a4SJeremy Kemp 
enqueueCopyImage(const Image & src,const Image & dst,const array<size_type,2> & src_origin,const array<size_type,2> & dst_origin,const array<size_type,2> & region,const vector<Event> * events=nullptr,Event * event=nullptr)10280*6fee86a4SJeremy Kemp inline cl_int enqueueCopyImage(
10281*6fee86a4SJeremy Kemp     const Image& src,
10282*6fee86a4SJeremy Kemp     const Image& dst,
10283*6fee86a4SJeremy Kemp     const array<size_type, 2>& src_origin,
10284*6fee86a4SJeremy Kemp     const array<size_type, 2>& dst_origin,
10285*6fee86a4SJeremy Kemp     const array<size_type, 2>& region,
10286*6fee86a4SJeremy Kemp     const vector<Event>* events = nullptr,
10287*6fee86a4SJeremy Kemp     Event* event = nullptr)
10288*6fee86a4SJeremy Kemp {
10289*6fee86a4SJeremy Kemp     return enqueueCopyImage(
10290*6fee86a4SJeremy Kemp         src,
10291*6fee86a4SJeremy Kemp         dst,
10292*6fee86a4SJeremy Kemp         { src_origin[0], src_origin[1], 0 },
10293*6fee86a4SJeremy Kemp         { dst_origin[0], dst_origin[1], 0 },
10294*6fee86a4SJeremy Kemp         { region[0], region[1], 1 },
10295*6fee86a4SJeremy Kemp         events,
10296*6fee86a4SJeremy Kemp         event);
10297*6fee86a4SJeremy Kemp }
10298*6fee86a4SJeremy Kemp 
enqueueCopyImageToBuffer(const Image & src,const Buffer & dst,const array<size_type,3> & src_origin,const array<size_type,3> & region,size_type dst_offset,const vector<Event> * events=nullptr,Event * event=nullptr)10299*6fee86a4SJeremy Kemp inline cl_int enqueueCopyImageToBuffer(
10300*6fee86a4SJeremy Kemp     const Image& src,
10301*6fee86a4SJeremy Kemp     const Buffer& dst,
10302*6fee86a4SJeremy Kemp     const array<size_type, 3>& src_origin,
10303*6fee86a4SJeremy Kemp     const array<size_type, 3>& region,
10304*6fee86a4SJeremy Kemp     size_type dst_offset,
10305*6fee86a4SJeremy Kemp     const vector<Event>* events = nullptr,
10306*6fee86a4SJeremy Kemp     Event* event = nullptr)
10307*6fee86a4SJeremy Kemp {
10308*6fee86a4SJeremy Kemp     cl_int error;
10309*6fee86a4SJeremy Kemp     CommandQueue queue = CommandQueue::getDefault(&error);
10310*6fee86a4SJeremy Kemp 
10311*6fee86a4SJeremy Kemp     if (error != CL_SUCCESS) {
10312*6fee86a4SJeremy Kemp         return error;
10313*6fee86a4SJeremy Kemp     }
10314*6fee86a4SJeremy Kemp 
10315*6fee86a4SJeremy Kemp     return queue.enqueueCopyImageToBuffer(
10316*6fee86a4SJeremy Kemp         src,
10317*6fee86a4SJeremy Kemp         dst,
10318*6fee86a4SJeremy Kemp         src_origin,
10319*6fee86a4SJeremy Kemp         region,
10320*6fee86a4SJeremy Kemp         dst_offset,
10321*6fee86a4SJeremy Kemp         events,
10322*6fee86a4SJeremy Kemp         event);
10323*6fee86a4SJeremy Kemp }
10324*6fee86a4SJeremy Kemp 
enqueueCopyImageToBuffer(const Image & src,const Buffer & dst,const array<size_type,2> & src_origin,const array<size_type,2> & region,size_type dst_offset,const vector<Event> * events=nullptr,Event * event=nullptr)10325*6fee86a4SJeremy Kemp inline cl_int enqueueCopyImageToBuffer(
10326*6fee86a4SJeremy Kemp     const Image& src,
10327*6fee86a4SJeremy Kemp     const Buffer& dst,
10328*6fee86a4SJeremy Kemp     const array<size_type, 2>& src_origin,
10329*6fee86a4SJeremy Kemp     const array<size_type, 2>& region,
10330*6fee86a4SJeremy Kemp     size_type dst_offset,
10331*6fee86a4SJeremy Kemp     const vector<Event>* events = nullptr,
10332*6fee86a4SJeremy Kemp     Event* event = nullptr)
10333*6fee86a4SJeremy Kemp {
10334*6fee86a4SJeremy Kemp     return enqueueCopyImageToBuffer(
10335*6fee86a4SJeremy Kemp         src,
10336*6fee86a4SJeremy Kemp         dst,
10337*6fee86a4SJeremy Kemp         { src_origin[0], src_origin[1], 0 },
10338*6fee86a4SJeremy Kemp         { region[0], region[1], 1 },
10339*6fee86a4SJeremy Kemp         dst_offset,
10340*6fee86a4SJeremy Kemp         events,
10341*6fee86a4SJeremy Kemp         event);
10342*6fee86a4SJeremy Kemp }
10343*6fee86a4SJeremy Kemp 
enqueueCopyBufferToImage(const Buffer & src,const Image & dst,size_type src_offset,const array<size_type,3> & dst_origin,const array<size_type,3> & region,const vector<Event> * events=nullptr,Event * event=nullptr)10344*6fee86a4SJeremy Kemp inline cl_int enqueueCopyBufferToImage(
10345*6fee86a4SJeremy Kemp     const Buffer& src,
10346*6fee86a4SJeremy Kemp     const Image& dst,
10347*6fee86a4SJeremy Kemp     size_type src_offset,
10348*6fee86a4SJeremy Kemp     const array<size_type, 3>& dst_origin,
10349*6fee86a4SJeremy Kemp     const array<size_type, 3>& region,
10350*6fee86a4SJeremy Kemp     const vector<Event>* events = nullptr,
10351*6fee86a4SJeremy Kemp     Event* event = nullptr)
10352*6fee86a4SJeremy Kemp {
10353*6fee86a4SJeremy Kemp     cl_int error;
10354*6fee86a4SJeremy Kemp     CommandQueue queue = CommandQueue::getDefault(&error);
10355*6fee86a4SJeremy Kemp 
10356*6fee86a4SJeremy Kemp     if (error != CL_SUCCESS) {
10357*6fee86a4SJeremy Kemp         return error;
10358*6fee86a4SJeremy Kemp     }
10359*6fee86a4SJeremy Kemp 
10360*6fee86a4SJeremy Kemp     return queue.enqueueCopyBufferToImage(
10361*6fee86a4SJeremy Kemp         src,
10362*6fee86a4SJeremy Kemp         dst,
10363*6fee86a4SJeremy Kemp         src_offset,
10364*6fee86a4SJeremy Kemp         dst_origin,
10365*6fee86a4SJeremy Kemp         region,
10366*6fee86a4SJeremy Kemp         events,
10367*6fee86a4SJeremy Kemp         event);
10368*6fee86a4SJeremy Kemp }
10369*6fee86a4SJeremy Kemp 
enqueueCopyBufferToImage(const Buffer & src,const Image & dst,size_type src_offset,const array<size_type,2> & dst_origin,const array<size_type,2> & region,const vector<Event> * events=nullptr,Event * event=nullptr)10370*6fee86a4SJeremy Kemp inline cl_int enqueueCopyBufferToImage(
10371*6fee86a4SJeremy Kemp     const Buffer& src,
10372*6fee86a4SJeremy Kemp     const Image& dst,
10373*6fee86a4SJeremy Kemp     size_type src_offset,
10374*6fee86a4SJeremy Kemp     const array<size_type, 2>& dst_origin,
10375*6fee86a4SJeremy Kemp     const array<size_type, 2>& region,
10376*6fee86a4SJeremy Kemp     const vector<Event>* events = nullptr,
10377*6fee86a4SJeremy Kemp     Event* event = nullptr)
10378*6fee86a4SJeremy Kemp {
10379*6fee86a4SJeremy Kemp     cl_int error;
10380*6fee86a4SJeremy Kemp     CommandQueue queue = CommandQueue::getDefault(&error);
10381*6fee86a4SJeremy Kemp 
10382*6fee86a4SJeremy Kemp     if (error != CL_SUCCESS) {
10383*6fee86a4SJeremy Kemp         return error;
10384*6fee86a4SJeremy Kemp     }
10385*6fee86a4SJeremy Kemp 
10386*6fee86a4SJeremy Kemp     return enqueueCopyBufferToImage(
10387*6fee86a4SJeremy Kemp         src,
10388*6fee86a4SJeremy Kemp         dst,
10389*6fee86a4SJeremy Kemp         src_offset,
10390*6fee86a4SJeremy Kemp         { dst_origin[0], dst_origin[1], 0 },
10391*6fee86a4SJeremy Kemp         { region[0], region[1], 1 },
10392*6fee86a4SJeremy Kemp         events,
10393*6fee86a4SJeremy Kemp         event);
10394*6fee86a4SJeremy Kemp }
10395*6fee86a4SJeremy Kemp 
flush(void)10396*6fee86a4SJeremy Kemp inline cl_int flush(void)
10397*6fee86a4SJeremy Kemp {
10398*6fee86a4SJeremy Kemp     cl_int error;
10399*6fee86a4SJeremy Kemp     CommandQueue queue = CommandQueue::getDefault(&error);
10400*6fee86a4SJeremy Kemp 
10401*6fee86a4SJeremy Kemp     if (error != CL_SUCCESS) {
10402*6fee86a4SJeremy Kemp         return error;
10403*6fee86a4SJeremy Kemp     }
10404*6fee86a4SJeremy Kemp 
10405*6fee86a4SJeremy Kemp     return queue.flush();
10406*6fee86a4SJeremy Kemp }
10407*6fee86a4SJeremy Kemp 
finish(void)10408*6fee86a4SJeremy Kemp inline cl_int finish(void)
10409*6fee86a4SJeremy Kemp {
10410*6fee86a4SJeremy Kemp     cl_int error;
10411*6fee86a4SJeremy Kemp     CommandQueue queue = CommandQueue::getDefault(&error);
10412*6fee86a4SJeremy Kemp 
10413*6fee86a4SJeremy Kemp     if (error != CL_SUCCESS) {
10414*6fee86a4SJeremy Kemp         return error;
10415*6fee86a4SJeremy Kemp     }
10416*6fee86a4SJeremy Kemp 
10417*6fee86a4SJeremy Kemp 
10418*6fee86a4SJeremy Kemp     return queue.finish();
10419*6fee86a4SJeremy Kemp }
10420*6fee86a4SJeremy Kemp 
10421*6fee86a4SJeremy Kemp class EnqueueArgs
10422*6fee86a4SJeremy Kemp {
10423*6fee86a4SJeremy Kemp private:
10424*6fee86a4SJeremy Kemp     CommandQueue queue_;
10425*6fee86a4SJeremy Kemp     const NDRange offset_;
10426*6fee86a4SJeremy Kemp     const NDRange global_;
10427*6fee86a4SJeremy Kemp     const NDRange local_;
10428*6fee86a4SJeremy Kemp     vector<Event> events_;
10429*6fee86a4SJeremy Kemp 
10430*6fee86a4SJeremy Kemp     template<typename... Ts>
10431*6fee86a4SJeremy Kemp     friend class KernelFunctor;
10432*6fee86a4SJeremy Kemp 
10433*6fee86a4SJeremy Kemp public:
EnqueueArgs(NDRange global)10434*6fee86a4SJeremy Kemp     EnqueueArgs(NDRange global) :
10435*6fee86a4SJeremy Kemp       queue_(CommandQueue::getDefault()),
10436*6fee86a4SJeremy Kemp       offset_(NullRange),
10437*6fee86a4SJeremy Kemp       global_(global),
10438*6fee86a4SJeremy Kemp       local_(NullRange)
10439*6fee86a4SJeremy Kemp     {
10440*6fee86a4SJeremy Kemp 
10441*6fee86a4SJeremy Kemp     }
10442*6fee86a4SJeremy Kemp 
EnqueueArgs(NDRange global,NDRange local)10443*6fee86a4SJeremy Kemp     EnqueueArgs(NDRange global, NDRange local) :
10444*6fee86a4SJeremy Kemp       queue_(CommandQueue::getDefault()),
10445*6fee86a4SJeremy Kemp       offset_(NullRange),
10446*6fee86a4SJeremy Kemp       global_(global),
10447*6fee86a4SJeremy Kemp       local_(local)
10448*6fee86a4SJeremy Kemp     {
10449*6fee86a4SJeremy Kemp 
10450*6fee86a4SJeremy Kemp     }
10451*6fee86a4SJeremy Kemp 
EnqueueArgs(NDRange offset,NDRange global,NDRange local)10452*6fee86a4SJeremy Kemp     EnqueueArgs(NDRange offset, NDRange global, NDRange local) :
10453*6fee86a4SJeremy Kemp       queue_(CommandQueue::getDefault()),
10454*6fee86a4SJeremy Kemp       offset_(offset),
10455*6fee86a4SJeremy Kemp       global_(global),
10456*6fee86a4SJeremy Kemp       local_(local)
10457*6fee86a4SJeremy Kemp     {
10458*6fee86a4SJeremy Kemp 
10459*6fee86a4SJeremy Kemp     }
10460*6fee86a4SJeremy Kemp 
EnqueueArgs(Event e,NDRange global)10461*6fee86a4SJeremy Kemp     EnqueueArgs(Event e, NDRange global) :
10462*6fee86a4SJeremy Kemp       queue_(CommandQueue::getDefault()),
10463*6fee86a4SJeremy Kemp       offset_(NullRange),
10464*6fee86a4SJeremy Kemp       global_(global),
10465*6fee86a4SJeremy Kemp       local_(NullRange)
10466*6fee86a4SJeremy Kemp     {
10467*6fee86a4SJeremy Kemp         events_.push_back(e);
10468*6fee86a4SJeremy Kemp     }
10469*6fee86a4SJeremy Kemp 
EnqueueArgs(Event e,NDRange global,NDRange local)10470*6fee86a4SJeremy Kemp     EnqueueArgs(Event e, NDRange global, NDRange local) :
10471*6fee86a4SJeremy Kemp       queue_(CommandQueue::getDefault()),
10472*6fee86a4SJeremy Kemp       offset_(NullRange),
10473*6fee86a4SJeremy Kemp       global_(global),
10474*6fee86a4SJeremy Kemp       local_(local)
10475*6fee86a4SJeremy Kemp     {
10476*6fee86a4SJeremy Kemp         events_.push_back(e);
10477*6fee86a4SJeremy Kemp     }
10478*6fee86a4SJeremy Kemp 
EnqueueArgs(Event e,NDRange offset,NDRange global,NDRange local)10479*6fee86a4SJeremy Kemp     EnqueueArgs(Event e, NDRange offset, NDRange global, NDRange local) :
10480*6fee86a4SJeremy Kemp       queue_(CommandQueue::getDefault()),
10481*6fee86a4SJeremy Kemp       offset_(offset),
10482*6fee86a4SJeremy Kemp       global_(global),
10483*6fee86a4SJeremy Kemp       local_(local)
10484*6fee86a4SJeremy Kemp     {
10485*6fee86a4SJeremy Kemp         events_.push_back(e);
10486*6fee86a4SJeremy Kemp     }
10487*6fee86a4SJeremy Kemp 
EnqueueArgs(const vector<Event> & events,NDRange global)10488*6fee86a4SJeremy Kemp     EnqueueArgs(const vector<Event> &events, NDRange global) :
10489*6fee86a4SJeremy Kemp       queue_(CommandQueue::getDefault()),
10490*6fee86a4SJeremy Kemp       offset_(NullRange),
10491*6fee86a4SJeremy Kemp       global_(global),
10492*6fee86a4SJeremy Kemp       local_(NullRange),
10493*6fee86a4SJeremy Kemp       events_(events)
10494*6fee86a4SJeremy Kemp     {
10495*6fee86a4SJeremy Kemp 
10496*6fee86a4SJeremy Kemp     }
10497*6fee86a4SJeremy Kemp 
EnqueueArgs(const vector<Event> & events,NDRange global,NDRange local)10498*6fee86a4SJeremy Kemp     EnqueueArgs(const vector<Event> &events, NDRange global, NDRange local) :
10499*6fee86a4SJeremy Kemp       queue_(CommandQueue::getDefault()),
10500*6fee86a4SJeremy Kemp       offset_(NullRange),
10501*6fee86a4SJeremy Kemp       global_(global),
10502*6fee86a4SJeremy Kemp       local_(local),
10503*6fee86a4SJeremy Kemp       events_(events)
10504*6fee86a4SJeremy Kemp     {
10505*6fee86a4SJeremy Kemp 
10506*6fee86a4SJeremy Kemp     }
10507*6fee86a4SJeremy Kemp 
EnqueueArgs(const vector<Event> & events,NDRange offset,NDRange global,NDRange local)10508*6fee86a4SJeremy Kemp     EnqueueArgs(const vector<Event> &events, NDRange offset, NDRange global, NDRange local) :
10509*6fee86a4SJeremy Kemp       queue_(CommandQueue::getDefault()),
10510*6fee86a4SJeremy Kemp       offset_(offset),
10511*6fee86a4SJeremy Kemp       global_(global),
10512*6fee86a4SJeremy Kemp       local_(local),
10513*6fee86a4SJeremy Kemp       events_(events)
10514*6fee86a4SJeremy Kemp     {
10515*6fee86a4SJeremy Kemp 
10516*6fee86a4SJeremy Kemp     }
10517*6fee86a4SJeremy Kemp 
EnqueueArgs(CommandQueue & queue,NDRange global)10518*6fee86a4SJeremy Kemp     EnqueueArgs(CommandQueue &queue, NDRange global) :
10519*6fee86a4SJeremy Kemp       queue_(queue),
10520*6fee86a4SJeremy Kemp       offset_(NullRange),
10521*6fee86a4SJeremy Kemp       global_(global),
10522*6fee86a4SJeremy Kemp       local_(NullRange)
10523*6fee86a4SJeremy Kemp     {
10524*6fee86a4SJeremy Kemp 
10525*6fee86a4SJeremy Kemp     }
10526*6fee86a4SJeremy Kemp 
EnqueueArgs(CommandQueue & queue,NDRange global,NDRange local)10527*6fee86a4SJeremy Kemp     EnqueueArgs(CommandQueue &queue, NDRange global, NDRange local) :
10528*6fee86a4SJeremy Kemp       queue_(queue),
10529*6fee86a4SJeremy Kemp       offset_(NullRange),
10530*6fee86a4SJeremy Kemp       global_(global),
10531*6fee86a4SJeremy Kemp       local_(local)
10532*6fee86a4SJeremy Kemp     {
10533*6fee86a4SJeremy Kemp 
10534*6fee86a4SJeremy Kemp     }
10535*6fee86a4SJeremy Kemp 
EnqueueArgs(CommandQueue & queue,NDRange offset,NDRange global,NDRange local)10536*6fee86a4SJeremy Kemp     EnqueueArgs(CommandQueue &queue, NDRange offset, NDRange global, NDRange local) :
10537*6fee86a4SJeremy Kemp       queue_(queue),
10538*6fee86a4SJeremy Kemp       offset_(offset),
10539*6fee86a4SJeremy Kemp       global_(global),
10540*6fee86a4SJeremy Kemp       local_(local)
10541*6fee86a4SJeremy Kemp     {
10542*6fee86a4SJeremy Kemp 
10543*6fee86a4SJeremy Kemp     }
10544*6fee86a4SJeremy Kemp 
EnqueueArgs(CommandQueue & queue,Event e,NDRange global)10545*6fee86a4SJeremy Kemp     EnqueueArgs(CommandQueue &queue, Event e, NDRange global) :
10546*6fee86a4SJeremy Kemp       queue_(queue),
10547*6fee86a4SJeremy Kemp       offset_(NullRange),
10548*6fee86a4SJeremy Kemp       global_(global),
10549*6fee86a4SJeremy Kemp       local_(NullRange)
10550*6fee86a4SJeremy Kemp     {
10551*6fee86a4SJeremy Kemp         events_.push_back(e);
10552*6fee86a4SJeremy Kemp     }
10553*6fee86a4SJeremy Kemp 
EnqueueArgs(CommandQueue & queue,Event e,NDRange global,NDRange local)10554*6fee86a4SJeremy Kemp     EnqueueArgs(CommandQueue &queue, Event e, NDRange global, NDRange local) :
10555*6fee86a4SJeremy Kemp       queue_(queue),
10556*6fee86a4SJeremy Kemp       offset_(NullRange),
10557*6fee86a4SJeremy Kemp       global_(global),
10558*6fee86a4SJeremy Kemp       local_(local)
10559*6fee86a4SJeremy Kemp     {
10560*6fee86a4SJeremy Kemp         events_.push_back(e);
10561*6fee86a4SJeremy Kemp     }
10562*6fee86a4SJeremy Kemp 
EnqueueArgs(CommandQueue & queue,Event e,NDRange offset,NDRange global,NDRange local)10563*6fee86a4SJeremy Kemp     EnqueueArgs(CommandQueue &queue, Event e, NDRange offset, NDRange global, NDRange local) :
10564*6fee86a4SJeremy Kemp       queue_(queue),
10565*6fee86a4SJeremy Kemp       offset_(offset),
10566*6fee86a4SJeremy Kemp       global_(global),
10567*6fee86a4SJeremy Kemp       local_(local)
10568*6fee86a4SJeremy Kemp     {
10569*6fee86a4SJeremy Kemp         events_.push_back(e);
10570*6fee86a4SJeremy Kemp     }
10571*6fee86a4SJeremy Kemp 
EnqueueArgs(CommandQueue & queue,const vector<Event> & events,NDRange global)10572*6fee86a4SJeremy Kemp     EnqueueArgs(CommandQueue &queue, const vector<Event> &events, NDRange global) :
10573*6fee86a4SJeremy Kemp       queue_(queue),
10574*6fee86a4SJeremy Kemp       offset_(NullRange),
10575*6fee86a4SJeremy Kemp       global_(global),
10576*6fee86a4SJeremy Kemp       local_(NullRange),
10577*6fee86a4SJeremy Kemp       events_(events)
10578*6fee86a4SJeremy Kemp     {
10579*6fee86a4SJeremy Kemp 
10580*6fee86a4SJeremy Kemp     }
10581*6fee86a4SJeremy Kemp 
EnqueueArgs(CommandQueue & queue,const vector<Event> & events,NDRange global,NDRange local)10582*6fee86a4SJeremy Kemp     EnqueueArgs(CommandQueue &queue, const vector<Event> &events, NDRange global, NDRange local) :
10583*6fee86a4SJeremy Kemp       queue_(queue),
10584*6fee86a4SJeremy Kemp       offset_(NullRange),
10585*6fee86a4SJeremy Kemp       global_(global),
10586*6fee86a4SJeremy Kemp       local_(local),
10587*6fee86a4SJeremy Kemp       events_(events)
10588*6fee86a4SJeremy Kemp     {
10589*6fee86a4SJeremy Kemp 
10590*6fee86a4SJeremy Kemp     }
10591*6fee86a4SJeremy Kemp 
EnqueueArgs(CommandQueue & queue,const vector<Event> & events,NDRange offset,NDRange global,NDRange local)10592*6fee86a4SJeremy Kemp     EnqueueArgs(CommandQueue &queue, const vector<Event> &events, NDRange offset, NDRange global, NDRange local) :
10593*6fee86a4SJeremy Kemp       queue_(queue),
10594*6fee86a4SJeremy Kemp       offset_(offset),
10595*6fee86a4SJeremy Kemp       global_(global),
10596*6fee86a4SJeremy Kemp       local_(local),
10597*6fee86a4SJeremy Kemp       events_(events)
10598*6fee86a4SJeremy Kemp     {
10599*6fee86a4SJeremy Kemp 
10600*6fee86a4SJeremy Kemp     }
10601*6fee86a4SJeremy Kemp };
10602*6fee86a4SJeremy Kemp 
10603*6fee86a4SJeremy Kemp 
10604*6fee86a4SJeremy Kemp //----------------------------------------------------------------------------------------------
10605*6fee86a4SJeremy Kemp 
10606*6fee86a4SJeremy Kemp 
10607*6fee86a4SJeremy Kemp /**
10608*6fee86a4SJeremy Kemp  * Type safe kernel functor.
10609*6fee86a4SJeremy Kemp  *
10610*6fee86a4SJeremy Kemp  */
10611*6fee86a4SJeremy Kemp template<typename... Ts>
10612*6fee86a4SJeremy Kemp class KernelFunctor
10613*6fee86a4SJeremy Kemp {
10614*6fee86a4SJeremy Kemp private:
10615*6fee86a4SJeremy Kemp     Kernel kernel_;
10616*6fee86a4SJeremy Kemp 
10617*6fee86a4SJeremy Kemp     template<int index, typename T0, typename... T1s>
setArgs(T0 && t0,T1s &&...t1s)10618*6fee86a4SJeremy Kemp     void setArgs(T0&& t0, T1s&&... t1s)
10619*6fee86a4SJeremy Kemp     {
10620*6fee86a4SJeremy Kemp         kernel_.setArg(index, t0);
10621*6fee86a4SJeremy Kemp         setArgs<index + 1, T1s...>(std::forward<T1s>(t1s)...);
10622*6fee86a4SJeremy Kemp     }
10623*6fee86a4SJeremy Kemp 
10624*6fee86a4SJeremy Kemp     template<int index, typename T0>
setArgs(T0 && t0)10625*6fee86a4SJeremy Kemp     void setArgs(T0&& t0)
10626*6fee86a4SJeremy Kemp     {
10627*6fee86a4SJeremy Kemp         kernel_.setArg(index, t0);
10628*6fee86a4SJeremy Kemp     }
10629*6fee86a4SJeremy Kemp 
10630*6fee86a4SJeremy Kemp     template<int index>
setArgs()10631*6fee86a4SJeremy Kemp     void setArgs()
10632*6fee86a4SJeremy Kemp     {
10633*6fee86a4SJeremy Kemp     }
10634*6fee86a4SJeremy Kemp 
10635*6fee86a4SJeremy Kemp 
10636*6fee86a4SJeremy Kemp public:
KernelFunctor(Kernel kernel)10637*6fee86a4SJeremy Kemp     KernelFunctor(Kernel kernel) : kernel_(kernel)
10638*6fee86a4SJeremy Kemp     {}
10639*6fee86a4SJeremy Kemp 
KernelFunctor(const Program & program,const string name,cl_int * err=nullptr)10640*6fee86a4SJeremy Kemp     KernelFunctor(
10641*6fee86a4SJeremy Kemp         const Program& program,
10642*6fee86a4SJeremy Kemp         const string name,
10643*6fee86a4SJeremy Kemp         cl_int * err = nullptr) :
10644*6fee86a4SJeremy Kemp         kernel_(program, name.c_str(), err)
10645*6fee86a4SJeremy Kemp     {}
10646*6fee86a4SJeremy Kemp 
10647*6fee86a4SJeremy Kemp     //! \brief Return type of the functor
10648*6fee86a4SJeremy Kemp     typedef Event result_type;
10649*6fee86a4SJeremy Kemp 
10650*6fee86a4SJeremy Kemp     /**
10651*6fee86a4SJeremy Kemp      * Enqueue kernel.
10652*6fee86a4SJeremy Kemp      * @param args Launch parameters of the kernel.
10653*6fee86a4SJeremy Kemp      * @param t0... List of kernel arguments based on the template type of the functor.
10654*6fee86a4SJeremy Kemp      */
operator ()(const EnqueueArgs & args,Ts...ts)10655*6fee86a4SJeremy Kemp     Event operator() (
10656*6fee86a4SJeremy Kemp         const EnqueueArgs& args,
10657*6fee86a4SJeremy Kemp         Ts... ts)
10658*6fee86a4SJeremy Kemp     {
10659*6fee86a4SJeremy Kemp         Event event;
10660*6fee86a4SJeremy Kemp         setArgs<0>(std::forward<Ts>(ts)...);
10661*6fee86a4SJeremy Kemp 
10662*6fee86a4SJeremy Kemp         args.queue_.enqueueNDRangeKernel(
10663*6fee86a4SJeremy Kemp             kernel_,
10664*6fee86a4SJeremy Kemp             args.offset_,
10665*6fee86a4SJeremy Kemp             args.global_,
10666*6fee86a4SJeremy Kemp             args.local_,
10667*6fee86a4SJeremy Kemp             &args.events_,
10668*6fee86a4SJeremy Kemp             &event);
10669*6fee86a4SJeremy Kemp 
10670*6fee86a4SJeremy Kemp         return event;
10671*6fee86a4SJeremy Kemp     }
10672*6fee86a4SJeremy Kemp 
10673*6fee86a4SJeremy Kemp     /**
10674*6fee86a4SJeremy Kemp     * Enqueue kernel with support for error code.
10675*6fee86a4SJeremy Kemp     * @param args Launch parameters of the kernel.
10676*6fee86a4SJeremy Kemp     * @param t0... List of kernel arguments based on the template type of the functor.
10677*6fee86a4SJeremy Kemp     * @param error Out parameter returning the error code from the execution.
10678*6fee86a4SJeremy Kemp     */
operator ()(const EnqueueArgs & args,Ts...ts,cl_int & error)10679*6fee86a4SJeremy Kemp     Event operator() (
10680*6fee86a4SJeremy Kemp         const EnqueueArgs& args,
10681*6fee86a4SJeremy Kemp         Ts... ts,
10682*6fee86a4SJeremy Kemp         cl_int &error)
10683*6fee86a4SJeremy Kemp     {
10684*6fee86a4SJeremy Kemp         Event event;
10685*6fee86a4SJeremy Kemp         setArgs<0>(std::forward<Ts>(ts)...);
10686*6fee86a4SJeremy Kemp 
10687*6fee86a4SJeremy Kemp         error = args.queue_.enqueueNDRangeKernel(
10688*6fee86a4SJeremy Kemp             kernel_,
10689*6fee86a4SJeremy Kemp             args.offset_,
10690*6fee86a4SJeremy Kemp             args.global_,
10691*6fee86a4SJeremy Kemp             args.local_,
10692*6fee86a4SJeremy Kemp             &args.events_,
10693*6fee86a4SJeremy Kemp             &event);
10694*6fee86a4SJeremy Kemp 
10695*6fee86a4SJeremy Kemp         return event;
10696*6fee86a4SJeremy Kemp     }
10697*6fee86a4SJeremy Kemp 
10698*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 200
setSVMPointers(const vector<void * > & pointerList)10699*6fee86a4SJeremy Kemp     cl_int setSVMPointers(const vector<void*> &pointerList)
10700*6fee86a4SJeremy Kemp     {
10701*6fee86a4SJeremy Kemp         return kernel_.setSVMPointers(pointerList);
10702*6fee86a4SJeremy Kemp     }
10703*6fee86a4SJeremy Kemp 
10704*6fee86a4SJeremy Kemp     template<typename T0, typename... T1s>
setSVMPointers(const T0 & t0,T1s &...ts)10705*6fee86a4SJeremy Kemp     cl_int setSVMPointers(const T0 &t0, T1s &... ts)
10706*6fee86a4SJeremy Kemp     {
10707*6fee86a4SJeremy Kemp         return kernel_.setSVMPointers(t0, ts...);
10708*6fee86a4SJeremy Kemp     }
10709*6fee86a4SJeremy Kemp #endif // #if CL_HPP_TARGET_OPENCL_VERSION >= 200
10710*6fee86a4SJeremy Kemp 
getKernel()10711*6fee86a4SJeremy Kemp     Kernel getKernel()
10712*6fee86a4SJeremy Kemp     {
10713*6fee86a4SJeremy Kemp         return kernel_;
10714*6fee86a4SJeremy Kemp     }
10715*6fee86a4SJeremy Kemp };
10716*6fee86a4SJeremy Kemp 
10717*6fee86a4SJeremy Kemp namespace compatibility {
10718*6fee86a4SJeremy Kemp     /**
10719*6fee86a4SJeremy Kemp      * Backward compatibility class to ensure that cl.hpp code works with opencl.hpp.
10720*6fee86a4SJeremy Kemp      * Please use KernelFunctor directly.
10721*6fee86a4SJeremy Kemp      */
10722*6fee86a4SJeremy Kemp     template<typename... Ts>
10723*6fee86a4SJeremy Kemp     struct make_kernel
10724*6fee86a4SJeremy Kemp     {
10725*6fee86a4SJeremy Kemp         typedef KernelFunctor<Ts...> FunctorType;
10726*6fee86a4SJeremy Kemp 
10727*6fee86a4SJeremy Kemp         FunctorType functor_;
10728*6fee86a4SJeremy Kemp 
make_kernelcl::compatibility::make_kernel10729*6fee86a4SJeremy Kemp         make_kernel(
10730*6fee86a4SJeremy Kemp             const Program& program,
10731*6fee86a4SJeremy Kemp             const string name,
10732*6fee86a4SJeremy Kemp             cl_int * err = nullptr) :
10733*6fee86a4SJeremy Kemp             functor_(FunctorType(program, name, err))
10734*6fee86a4SJeremy Kemp         {}
10735*6fee86a4SJeremy Kemp 
make_kernelcl::compatibility::make_kernel10736*6fee86a4SJeremy Kemp         make_kernel(
10737*6fee86a4SJeremy Kemp             const Kernel kernel) :
10738*6fee86a4SJeremy Kemp             functor_(FunctorType(kernel))
10739*6fee86a4SJeremy Kemp         {}
10740*6fee86a4SJeremy Kemp 
10741*6fee86a4SJeremy Kemp         //! \brief Return type of the functor
10742*6fee86a4SJeremy Kemp         typedef Event result_type;
10743*6fee86a4SJeremy Kemp 
10744*6fee86a4SJeremy Kemp         //! \brief Function signature of kernel functor with no event dependency.
10745*6fee86a4SJeremy Kemp         typedef Event type_(
10746*6fee86a4SJeremy Kemp             const EnqueueArgs&,
10747*6fee86a4SJeremy Kemp             Ts...);
10748*6fee86a4SJeremy Kemp 
operator ()cl::compatibility::make_kernel10749*6fee86a4SJeremy Kemp         Event operator()(
10750*6fee86a4SJeremy Kemp             const EnqueueArgs& enqueueArgs,
10751*6fee86a4SJeremy Kemp             Ts... args)
10752*6fee86a4SJeremy Kemp         {
10753*6fee86a4SJeremy Kemp             return functor_(
10754*6fee86a4SJeremy Kemp                 enqueueArgs, args...);
10755*6fee86a4SJeremy Kemp         }
10756*6fee86a4SJeremy Kemp     };
10757*6fee86a4SJeremy Kemp } // namespace compatibility
10758*6fee86a4SJeremy Kemp 
10759*6fee86a4SJeremy Kemp #ifdef cl_khr_semaphore
10760*6fee86a4SJeremy Kemp 
10761*6fee86a4SJeremy Kemp #ifdef cl_khr_external_semaphore
10762*6fee86a4SJeremy Kemp enum ExternalSemaphoreType : cl_external_semaphore_handle_type_khr
10763*6fee86a4SJeremy Kemp {
10764*6fee86a4SJeremy Kemp     None = 0,
10765*6fee86a4SJeremy Kemp #ifdef cl_khr_external_semaphore_dx_fence
10766*6fee86a4SJeremy Kemp     D3D12Fence = CL_SEMAPHORE_HANDLE_D3D12_FENCE_KHR,
10767*6fee86a4SJeremy Kemp #endif
10768*6fee86a4SJeremy Kemp #ifdef cl_khr_external_semaphore_opaque_fd
10769*6fee86a4SJeremy Kemp     OpaqueFd = CL_SEMAPHORE_HANDLE_OPAQUE_FD_KHR,
10770*6fee86a4SJeremy Kemp #endif
10771*6fee86a4SJeremy Kemp #ifdef cl_khr_external_semaphore_sync_fd
10772*6fee86a4SJeremy Kemp     SyncFd = CL_SEMAPHORE_HANDLE_SYNC_FD_KHR,
10773*6fee86a4SJeremy Kemp #endif
10774*6fee86a4SJeremy Kemp #ifdef cl_khr_external_semaphore_win32
10775*6fee86a4SJeremy Kemp     OpaqueWin32 = CL_SEMAPHORE_HANDLE_OPAQUE_WIN32_KHR,
10776*6fee86a4SJeremy Kemp     OpaqueWin32Kmt = CL_SEMAPHORE_HANDLE_OPAQUE_WIN32_KMT_KHR,
10777*6fee86a4SJeremy Kemp #endif // cl_khr_external_semaphore_win32
10778*6fee86a4SJeremy Kemp };
10779*6fee86a4SJeremy Kemp #endif // cl_khr_external_semaphore
10780*6fee86a4SJeremy Kemp 
10781*6fee86a4SJeremy Kemp class Semaphore : public detail::Wrapper<cl_semaphore_khr>
10782*6fee86a4SJeremy Kemp {
10783*6fee86a4SJeremy Kemp public:
Semaphore()10784*6fee86a4SJeremy Kemp     Semaphore() : detail::Wrapper<cl_type>() {}
Semaphore(const Context & context,const vector<cl_semaphore_properties_khr> & sema_props,cl_int * err=nullptr)10785*6fee86a4SJeremy Kemp     Semaphore(
10786*6fee86a4SJeremy Kemp         const Context &context,
10787*6fee86a4SJeremy Kemp         const vector<cl_semaphore_properties_khr>& sema_props,
10788*6fee86a4SJeremy Kemp         cl_int *err = nullptr)
10789*6fee86a4SJeremy Kemp     {
10790*6fee86a4SJeremy Kemp         /* initialization of addresses to extension functions (it is done only once) */
10791*6fee86a4SJeremy Kemp         std::call_once(ext_init_, initExtensions, context);
10792*6fee86a4SJeremy Kemp 
10793*6fee86a4SJeremy Kemp         cl_int error = CL_INVALID_OPERATION;
10794*6fee86a4SJeremy Kemp 
10795*6fee86a4SJeremy Kemp         if (pfn_clCreateSemaphoreWithPropertiesKHR)
10796*6fee86a4SJeremy Kemp         {
10797*6fee86a4SJeremy Kemp             object_ = pfn_clCreateSemaphoreWithPropertiesKHR(
10798*6fee86a4SJeremy Kemp                 context(),
10799*6fee86a4SJeremy Kemp                 sema_props.data(),
10800*6fee86a4SJeremy Kemp                 &error);
10801*6fee86a4SJeremy Kemp         }
10802*6fee86a4SJeremy Kemp 
10803*6fee86a4SJeremy Kemp         detail::errHandler(error, __CREATE_SEMAPHORE_KHR_WITH_PROPERTIES_ERR);
10804*6fee86a4SJeremy Kemp 
10805*6fee86a4SJeremy Kemp         if (err != nullptr) {
10806*6fee86a4SJeremy Kemp             *err = error;
10807*6fee86a4SJeremy Kemp         }
10808*6fee86a4SJeremy Kemp     }
Semaphore(const vector<cl_semaphore_properties_khr> & sema_props,cl_int * err=nullptr)10809*6fee86a4SJeremy Kemp     Semaphore(
10810*6fee86a4SJeremy Kemp         const vector<cl_semaphore_properties_khr>& sema_props,
10811*6fee86a4SJeremy Kemp         cl_int* err = nullptr):Semaphore(Context::getDefault(err), sema_props, err) {}
10812*6fee86a4SJeremy Kemp 
Semaphore(const cl_semaphore_khr & semaphore,bool retainObject=false)10813*6fee86a4SJeremy Kemp     explicit Semaphore(const cl_semaphore_khr& semaphore, bool retainObject = false) :
10814*6fee86a4SJeremy Kemp         detail::Wrapper<cl_type>(semaphore, retainObject) {}
operator =(const cl_semaphore_khr & rhs)10815*6fee86a4SJeremy Kemp     Semaphore& operator = (const cl_semaphore_khr& rhs) {
10816*6fee86a4SJeremy Kemp         detail::Wrapper<cl_type>::operator=(rhs);
10817*6fee86a4SJeremy Kemp         return *this;
10818*6fee86a4SJeremy Kemp     }
10819*6fee86a4SJeremy Kemp     template <typename T>
getInfo(cl_semaphore_info_khr name,T * param) const10820*6fee86a4SJeremy Kemp     cl_int getInfo(cl_semaphore_info_khr name, T* param) const
10821*6fee86a4SJeremy Kemp     {
10822*6fee86a4SJeremy Kemp         if (pfn_clGetSemaphoreInfoKHR == nullptr) {
10823*6fee86a4SJeremy Kemp             return detail::errHandler(CL_INVALID_OPERATION,
10824*6fee86a4SJeremy Kemp                                       __GET_SEMAPHORE_KHR_INFO_ERR);
10825*6fee86a4SJeremy Kemp         }
10826*6fee86a4SJeremy Kemp 
10827*6fee86a4SJeremy Kemp         return detail::errHandler(
10828*6fee86a4SJeremy Kemp             detail::getInfo(pfn_clGetSemaphoreInfoKHR, object_, name, param),
10829*6fee86a4SJeremy Kemp             __GET_SEMAPHORE_KHR_INFO_ERR);
10830*6fee86a4SJeremy Kemp     }
10831*6fee86a4SJeremy Kemp     template <cl_semaphore_info_khr name> typename
10832*6fee86a4SJeremy Kemp     detail::param_traits<detail::cl_semaphore_info_khr, name>::param_type
getInfo(cl_int * err=nullptr) const10833*6fee86a4SJeremy Kemp     getInfo(cl_int* err = nullptr) const
10834*6fee86a4SJeremy Kemp     {
10835*6fee86a4SJeremy Kemp         typename detail::param_traits<
10836*6fee86a4SJeremy Kemp             detail::cl_semaphore_info_khr, name>::param_type param;
10837*6fee86a4SJeremy Kemp         cl_int result = getInfo(name, &param);
10838*6fee86a4SJeremy Kemp         if (err != nullptr) {
10839*6fee86a4SJeremy Kemp             *err = result;
10840*6fee86a4SJeremy Kemp         }
10841*6fee86a4SJeremy Kemp         return param;
10842*6fee86a4SJeremy Kemp     }
10843*6fee86a4SJeremy Kemp 
10844*6fee86a4SJeremy Kemp #ifdef cl_khr_external_semaphore
10845*6fee86a4SJeremy Kemp     template <typename T>
getHandleForTypeKHR(const Device & device,cl_external_semaphore_handle_type_khr name,T * param) const10846*6fee86a4SJeremy Kemp     cl_int getHandleForTypeKHR(
10847*6fee86a4SJeremy Kemp         const Device& device, cl_external_semaphore_handle_type_khr name, T* param) const
10848*6fee86a4SJeremy Kemp     {
10849*6fee86a4SJeremy Kemp         if (pfn_clGetSemaphoreHandleForTypeKHR == nullptr) {
10850*6fee86a4SJeremy Kemp             return detail::errHandler(CL_INVALID_OPERATION,
10851*6fee86a4SJeremy Kemp                                       __GET_SEMAPHORE_HANDLE_FOR_TYPE_KHR_ERR);
10852*6fee86a4SJeremy Kemp         }
10853*6fee86a4SJeremy Kemp 
10854*6fee86a4SJeremy Kemp         return detail::errHandler(
10855*6fee86a4SJeremy Kemp             detail::getInfo(
10856*6fee86a4SJeremy Kemp                 pfn_clGetSemaphoreHandleForTypeKHR, object_, device(), name, param),
10857*6fee86a4SJeremy Kemp                 __GET_SEMAPHORE_HANDLE_FOR_TYPE_KHR_ERR);
10858*6fee86a4SJeremy Kemp     }
10859*6fee86a4SJeremy Kemp 
10860*6fee86a4SJeremy Kemp     template <cl_external_semaphore_handle_type_khr type> typename
10861*6fee86a4SJeremy Kemp     detail::param_traits<detail::cl_external_semaphore_handle_type_khr, type>::param_type
getHandleForTypeKHR(const Device & device,cl_int * err=nullptr) const10862*6fee86a4SJeremy Kemp         getHandleForTypeKHR(const Device& device, cl_int* err = nullptr) const
10863*6fee86a4SJeremy Kemp     {
10864*6fee86a4SJeremy Kemp         typename detail::param_traits<
10865*6fee86a4SJeremy Kemp         detail::cl_external_semaphore_handle_type_khr, type>::param_type param;
10866*6fee86a4SJeremy Kemp         cl_int result = getHandleForTypeKHR(device, type, &param);
10867*6fee86a4SJeremy Kemp         if (err != nullptr) {
10868*6fee86a4SJeremy Kemp             *err = result;
10869*6fee86a4SJeremy Kemp         }
10870*6fee86a4SJeremy Kemp         return param;
10871*6fee86a4SJeremy Kemp     }
10872*6fee86a4SJeremy Kemp #endif // cl_khr_external_semaphore
10873*6fee86a4SJeremy Kemp 
retain()10874*6fee86a4SJeremy Kemp     cl_int retain()
10875*6fee86a4SJeremy Kemp     {
10876*6fee86a4SJeremy Kemp         if (pfn_clRetainSemaphoreKHR == nullptr) {
10877*6fee86a4SJeremy Kemp             return detail::errHandler(CL_INVALID_OPERATION,
10878*6fee86a4SJeremy Kemp                                       __RETAIN_SEMAPHORE_KHR_ERR);
10879*6fee86a4SJeremy Kemp         }
10880*6fee86a4SJeremy Kemp         return pfn_clRetainSemaphoreKHR(object_);
10881*6fee86a4SJeremy Kemp     }
10882*6fee86a4SJeremy Kemp 
release()10883*6fee86a4SJeremy Kemp     cl_int release()
10884*6fee86a4SJeremy Kemp     {
10885*6fee86a4SJeremy Kemp         if (pfn_clReleaseSemaphoreKHR == nullptr) {
10886*6fee86a4SJeremy Kemp             return detail::errHandler(CL_INVALID_OPERATION,
10887*6fee86a4SJeremy Kemp                                       __RELEASE_SEMAPHORE_KHR_ERR);
10888*6fee86a4SJeremy Kemp         }
10889*6fee86a4SJeremy Kemp         return pfn_clReleaseSemaphoreKHR(object_);
10890*6fee86a4SJeremy Kemp     }
10891*6fee86a4SJeremy Kemp 
10892*6fee86a4SJeremy Kemp private:
10893*6fee86a4SJeremy Kemp     static std::once_flag ext_init_;
10894*6fee86a4SJeremy Kemp 
initExtensions(const Context & context)10895*6fee86a4SJeremy Kemp     static void initExtensions(const Context& context)
10896*6fee86a4SJeremy Kemp     {
10897*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 120
10898*6fee86a4SJeremy Kemp         Device device = context.getInfo<CL_CONTEXT_DEVICES>().at(0);
10899*6fee86a4SJeremy Kemp         cl_platform_id platform = device.getInfo<CL_DEVICE_PLATFORM>()();
10900*6fee86a4SJeremy Kemp         CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clCreateSemaphoreWithPropertiesKHR);
10901*6fee86a4SJeremy Kemp         CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clReleaseSemaphoreKHR);
10902*6fee86a4SJeremy Kemp         CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clRetainSemaphoreKHR);
10903*6fee86a4SJeremy Kemp         CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clEnqueueWaitSemaphoresKHR);
10904*6fee86a4SJeremy Kemp         CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clEnqueueSignalSemaphoresKHR);
10905*6fee86a4SJeremy Kemp         CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clGetSemaphoreInfoKHR);
10906*6fee86a4SJeremy Kemp #ifdef cl_khr_external_semaphore
10907*6fee86a4SJeremy Kemp         CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clGetSemaphoreHandleForTypeKHR);
10908*6fee86a4SJeremy Kemp #endif // cl_khr_external_semaphore
10909*6fee86a4SJeremy Kemp 
10910*6fee86a4SJeremy Kemp #else
10911*6fee86a4SJeremy Kemp         CL_HPP_INIT_CL_EXT_FCN_PTR_(clCreateSemaphoreWithPropertiesKHR);
10912*6fee86a4SJeremy Kemp         CL_HPP_INIT_CL_EXT_FCN_PTR_(clReleaseSemaphoreKHR);
10913*6fee86a4SJeremy Kemp         CL_HPP_INIT_CL_EXT_FCN_PTR_(clRetainSemaphoreKHR);
10914*6fee86a4SJeremy Kemp         CL_HPP_INIT_CL_EXT_FCN_PTR_(clEnqueueWaitSemaphoresKHR);
10915*6fee86a4SJeremy Kemp         CL_HPP_INIT_CL_EXT_FCN_PTR_(clEnqueueSignalSemaphoresKHR);
10916*6fee86a4SJeremy Kemp         CL_HPP_INIT_CL_EXT_FCN_PTR_(clGetSemaphoreInfoKHR);
10917*6fee86a4SJeremy Kemp #ifdef cl_khr_external_semaphore
10918*6fee86a4SJeremy Kemp         CL_HPP_INIT_CL_EXT_FCN_PTR_(clGetSemaphoreHandleForTypeKHR);
10919*6fee86a4SJeremy Kemp #endif // cl_khr_external_semaphore
10920*6fee86a4SJeremy Kemp 
10921*6fee86a4SJeremy Kemp #endif
10922*6fee86a4SJeremy Kemp         if ((pfn_clCreateSemaphoreWithPropertiesKHR == nullptr) &&
10923*6fee86a4SJeremy Kemp             (pfn_clReleaseSemaphoreKHR              == nullptr) &&
10924*6fee86a4SJeremy Kemp             (pfn_clRetainSemaphoreKHR               == nullptr) &&
10925*6fee86a4SJeremy Kemp             (pfn_clEnqueueWaitSemaphoresKHR         == nullptr) &&
10926*6fee86a4SJeremy Kemp             (pfn_clEnqueueSignalSemaphoresKHR       == nullptr) &&
10927*6fee86a4SJeremy Kemp #ifdef cl_khr_external_semaphore
10928*6fee86a4SJeremy Kemp             (pfn_clGetSemaphoreHandleForTypeKHR     == nullptr) &&
10929*6fee86a4SJeremy Kemp #endif // cl_khr_external_semaphore
10930*6fee86a4SJeremy Kemp             (pfn_clGetSemaphoreInfoKHR              == nullptr))
10931*6fee86a4SJeremy Kemp         {
10932*6fee86a4SJeremy Kemp             detail::errHandler(CL_INVALID_VALUE, __CREATE_SEMAPHORE_KHR_WITH_PROPERTIES_ERR);
10933*6fee86a4SJeremy Kemp         }
10934*6fee86a4SJeremy Kemp     }
10935*6fee86a4SJeremy Kemp 
10936*6fee86a4SJeremy Kemp };
10937*6fee86a4SJeremy Kemp 
10938*6fee86a4SJeremy Kemp CL_HPP_DEFINE_STATIC_MEMBER_ std::once_flag Semaphore::ext_init_;
10939*6fee86a4SJeremy Kemp 
enqueueWaitSemaphores(const vector<Semaphore> & sema_objects,const vector<cl_semaphore_payload_khr> & sema_payloads,const vector<Event> * events_wait_list,Event * event) const10940*6fee86a4SJeremy Kemp inline cl_int CommandQueue::enqueueWaitSemaphores(
10941*6fee86a4SJeremy Kemp     const vector<Semaphore> &sema_objects,
10942*6fee86a4SJeremy Kemp     const vector<cl_semaphore_payload_khr> &sema_payloads,
10943*6fee86a4SJeremy Kemp     const vector<Event>* events_wait_list,
10944*6fee86a4SJeremy Kemp     Event *event) const
10945*6fee86a4SJeremy Kemp {
10946*6fee86a4SJeremy Kemp     cl_event tmp;
10947*6fee86a4SJeremy Kemp     cl_int err = CL_INVALID_OPERATION;
10948*6fee86a4SJeremy Kemp 
10949*6fee86a4SJeremy Kemp     if (pfn_clEnqueueWaitSemaphoresKHR != nullptr) {
10950*6fee86a4SJeremy Kemp         err = pfn_clEnqueueWaitSemaphoresKHR(
10951*6fee86a4SJeremy Kemp                 object_,
10952*6fee86a4SJeremy Kemp                 (cl_uint)sema_objects.size(),
10953*6fee86a4SJeremy Kemp                 (const cl_semaphore_khr *) &sema_objects.front(),
10954*6fee86a4SJeremy Kemp                 (sema_payloads.size() > 0) ? &sema_payloads.front() : nullptr,
10955*6fee86a4SJeremy Kemp                 (events_wait_list != nullptr) ? (cl_uint) events_wait_list->size() : 0,
10956*6fee86a4SJeremy Kemp                 (events_wait_list != nullptr && events_wait_list->size() > 0) ? (cl_event*) &events_wait_list->front() : nullptr,
10957*6fee86a4SJeremy Kemp                 (event != nullptr) ? &tmp : nullptr);
10958*6fee86a4SJeremy Kemp     }
10959*6fee86a4SJeremy Kemp 
10960*6fee86a4SJeremy Kemp     detail::errHandler(err, __ENQUEUE_WAIT_SEMAPHORE_KHR_ERR);
10961*6fee86a4SJeremy Kemp 
10962*6fee86a4SJeremy Kemp     if (event != nullptr && err == CL_SUCCESS)
10963*6fee86a4SJeremy Kemp         *event = tmp;
10964*6fee86a4SJeremy Kemp 
10965*6fee86a4SJeremy Kemp     return err;
10966*6fee86a4SJeremy Kemp }
10967*6fee86a4SJeremy Kemp 
enqueueSignalSemaphores(const vector<Semaphore> & sema_objects,const vector<cl_semaphore_payload_khr> & sema_payloads,const vector<Event> * events_wait_list,Event * event)10968*6fee86a4SJeremy Kemp inline cl_int CommandQueue::enqueueSignalSemaphores(
10969*6fee86a4SJeremy Kemp     const vector<Semaphore> &sema_objects,
10970*6fee86a4SJeremy Kemp     const vector<cl_semaphore_payload_khr>& sema_payloads,
10971*6fee86a4SJeremy Kemp     const vector<Event>* events_wait_list,
10972*6fee86a4SJeremy Kemp     Event* event)
10973*6fee86a4SJeremy Kemp {
10974*6fee86a4SJeremy Kemp     cl_event tmp;
10975*6fee86a4SJeremy Kemp     cl_int err = CL_INVALID_OPERATION;
10976*6fee86a4SJeremy Kemp 
10977*6fee86a4SJeremy Kemp     if (pfn_clEnqueueSignalSemaphoresKHR != nullptr) {
10978*6fee86a4SJeremy Kemp         err = pfn_clEnqueueSignalSemaphoresKHR(
10979*6fee86a4SJeremy Kemp                 object_,
10980*6fee86a4SJeremy Kemp                 (cl_uint)sema_objects.size(),
10981*6fee86a4SJeremy Kemp                 (const cl_semaphore_khr*) &sema_objects.front(),
10982*6fee86a4SJeremy Kemp                 (sema_payloads.size() > 0) ? &sema_payloads.front() : nullptr,
10983*6fee86a4SJeremy Kemp                 (events_wait_list != nullptr) ? (cl_uint) events_wait_list->size() : 0,
10984*6fee86a4SJeremy Kemp                 (events_wait_list != nullptr && events_wait_list->size() > 0) ? (cl_event*) &events_wait_list->front() : nullptr,
10985*6fee86a4SJeremy Kemp                 (event != nullptr) ? &tmp : nullptr);
10986*6fee86a4SJeremy Kemp     }
10987*6fee86a4SJeremy Kemp 
10988*6fee86a4SJeremy Kemp     detail::errHandler(err, __ENQUEUE_SIGNAL_SEMAPHORE_KHR_ERR);
10989*6fee86a4SJeremy Kemp 
10990*6fee86a4SJeremy Kemp     if (event != nullptr && err == CL_SUCCESS)
10991*6fee86a4SJeremy Kemp         *event = tmp;
10992*6fee86a4SJeremy Kemp 
10993*6fee86a4SJeremy Kemp     return err;
10994*6fee86a4SJeremy Kemp }
10995*6fee86a4SJeremy Kemp 
10996*6fee86a4SJeremy Kemp #endif // cl_khr_semaphore
10997*6fee86a4SJeremy Kemp 
10998*6fee86a4SJeremy Kemp #if defined(cl_khr_command_buffer)
10999*6fee86a4SJeremy Kemp /*! \class CommandBufferKhr
11000*6fee86a4SJeremy Kemp  * \brief CommandBufferKhr interface for cl_command_buffer_khr.
11001*6fee86a4SJeremy Kemp  */
11002*6fee86a4SJeremy Kemp class CommandBufferKhr : public detail::Wrapper<cl_command_buffer_khr>
11003*6fee86a4SJeremy Kemp {
11004*6fee86a4SJeremy Kemp public:
11005*6fee86a4SJeremy Kemp     //! \brief Default constructor - initializes to nullptr.
CommandBufferKhr()11006*6fee86a4SJeremy Kemp     CommandBufferKhr() : detail::Wrapper<cl_type>() { }
11007*6fee86a4SJeremy Kemp 
CommandBufferKhr(const vector<CommandQueue> & queues,cl_command_buffer_properties_khr properties=0,cl_int * errcode_ret=nullptr)11008*6fee86a4SJeremy Kemp     explicit CommandBufferKhr(const vector<CommandQueue> &queues,
11009*6fee86a4SJeremy Kemp         cl_command_buffer_properties_khr properties = 0,
11010*6fee86a4SJeremy Kemp         cl_int* errcode_ret = nullptr)
11011*6fee86a4SJeremy Kemp     {
11012*6fee86a4SJeremy Kemp         cl_command_buffer_properties_khr command_buffer_properties[] = {
11013*6fee86a4SJeremy Kemp             CL_COMMAND_BUFFER_FLAGS_KHR, properties, 0
11014*6fee86a4SJeremy Kemp         };
11015*6fee86a4SJeremy Kemp 
11016*6fee86a4SJeremy Kemp         /* initialization of addresses to extension functions (it is done only once) */
11017*6fee86a4SJeremy Kemp         std::call_once(ext_init_, [&] { initExtensions(queues[0].getInfo<CL_QUEUE_DEVICE>()); });
11018*6fee86a4SJeremy Kemp         cl_int error = CL_INVALID_OPERATION;
11019*6fee86a4SJeremy Kemp 
11020*6fee86a4SJeremy Kemp         static_assert(sizeof(cl::CommandQueue) == sizeof(cl_command_queue),
11021*6fee86a4SJeremy Kemp             "Size of cl::CommandQueue must be equal to size of cl_command_queue");
11022*6fee86a4SJeremy Kemp 
11023*6fee86a4SJeremy Kemp         if (pfn_clCreateCommandBufferKHR)
11024*6fee86a4SJeremy Kemp         {
11025*6fee86a4SJeremy Kemp             object_ = pfn_clCreateCommandBufferKHR((cl_uint) queues.size(),
11026*6fee86a4SJeremy Kemp                 (cl_command_queue *) &queues.front(),
11027*6fee86a4SJeremy Kemp                 command_buffer_properties,
11028*6fee86a4SJeremy Kemp                 &error);
11029*6fee86a4SJeremy Kemp         }
11030*6fee86a4SJeremy Kemp 
11031*6fee86a4SJeremy Kemp         detail::errHandler(error, __CREATE_COMMAND_BUFFER_KHR_ERR);
11032*6fee86a4SJeremy Kemp         if (errcode_ret != nullptr) {
11033*6fee86a4SJeremy Kemp             *errcode_ret = error;
11034*6fee86a4SJeremy Kemp         }
11035*6fee86a4SJeremy Kemp     }
11036*6fee86a4SJeremy Kemp 
CommandBufferKhr(const cl_command_buffer_khr & commandBufferKhr,bool retainObject=false)11037*6fee86a4SJeremy Kemp     explicit CommandBufferKhr(const cl_command_buffer_khr& commandBufferKhr, bool retainObject = false) :
11038*6fee86a4SJeremy Kemp         detail::Wrapper<cl_type>(commandBufferKhr, retainObject) { }
11039*6fee86a4SJeremy Kemp 
operator =(const cl_command_buffer_khr & rhs)11040*6fee86a4SJeremy Kemp     CommandBufferKhr& operator=(const cl_command_buffer_khr& rhs)
11041*6fee86a4SJeremy Kemp     {
11042*6fee86a4SJeremy Kemp         detail::Wrapper<cl_type>::operator=(rhs);
11043*6fee86a4SJeremy Kemp         return *this;
11044*6fee86a4SJeremy Kemp     }
11045*6fee86a4SJeremy Kemp 
11046*6fee86a4SJeremy Kemp     template <typename T>
getInfo(cl_command_buffer_info_khr name,T * param) const11047*6fee86a4SJeremy Kemp     cl_int getInfo(cl_command_buffer_info_khr name, T* param) const
11048*6fee86a4SJeremy Kemp     {
11049*6fee86a4SJeremy Kemp         if (pfn_clGetCommandBufferInfoKHR == nullptr) {
11050*6fee86a4SJeremy Kemp             return detail::errHandler(CL_INVALID_OPERATION,
11051*6fee86a4SJeremy Kemp                     __GET_COMMAND_BUFFER_INFO_KHR_ERR);
11052*6fee86a4SJeremy Kemp         }
11053*6fee86a4SJeremy Kemp         return detail::errHandler(
11054*6fee86a4SJeremy Kemp             detail::getInfo(pfn_clGetCommandBufferInfoKHR, object_, name, param),
11055*6fee86a4SJeremy Kemp                 __GET_COMMAND_BUFFER_INFO_KHR_ERR);
11056*6fee86a4SJeremy Kemp     }
11057*6fee86a4SJeremy Kemp 
11058*6fee86a4SJeremy Kemp     template <cl_command_buffer_info_khr name> typename
11059*6fee86a4SJeremy Kemp         detail::param_traits<detail::cl_command_buffer_info_khr, name>::param_type
getInfo(cl_int * err=nullptr) const11060*6fee86a4SJeremy Kemp         getInfo(cl_int* err = nullptr) const
11061*6fee86a4SJeremy Kemp     {
11062*6fee86a4SJeremy Kemp         typename detail::param_traits<
11063*6fee86a4SJeremy Kemp             detail::cl_command_buffer_info_khr, name>::param_type param;
11064*6fee86a4SJeremy Kemp         cl_int result = getInfo(name, &param);
11065*6fee86a4SJeremy Kemp         if (err != nullptr) {
11066*6fee86a4SJeremy Kemp             *err = result;
11067*6fee86a4SJeremy Kemp         }
11068*6fee86a4SJeremy Kemp         return param;
11069*6fee86a4SJeremy Kemp     }
11070*6fee86a4SJeremy Kemp 
finalizeCommandBuffer() const11071*6fee86a4SJeremy Kemp     cl_int finalizeCommandBuffer() const
11072*6fee86a4SJeremy Kemp     {
11073*6fee86a4SJeremy Kemp         return detail::errHandler(::clFinalizeCommandBufferKHR(object_), __FINALIZE_COMMAND_BUFFER_KHR_ERR);
11074*6fee86a4SJeremy Kemp     }
11075*6fee86a4SJeremy Kemp 
enqueueCommandBuffer(vector<CommandQueue> & queues,const vector<Event> * events=nullptr,Event * event=nullptr)11076*6fee86a4SJeremy Kemp     cl_int enqueueCommandBuffer(vector<CommandQueue> &queues,
11077*6fee86a4SJeremy Kemp         const vector<Event>* events = nullptr,
11078*6fee86a4SJeremy Kemp         Event* event = nullptr)
11079*6fee86a4SJeremy Kemp     {
11080*6fee86a4SJeremy Kemp         if (pfn_clEnqueueCommandBufferKHR == nullptr) {
11081*6fee86a4SJeremy Kemp             return detail::errHandler(CL_INVALID_OPERATION,
11082*6fee86a4SJeremy Kemp                     __ENQUEUE_COMMAND_BUFFER_KHR_ERR);
11083*6fee86a4SJeremy Kemp         }
11084*6fee86a4SJeremy Kemp 
11085*6fee86a4SJeremy Kemp          static_assert(sizeof(cl::CommandQueue) == sizeof(cl_command_queue),
11086*6fee86a4SJeremy Kemp             "Size of cl::CommandQueue must be equal to size of cl_command_queue");
11087*6fee86a4SJeremy Kemp 
11088*6fee86a4SJeremy Kemp         return detail::errHandler(pfn_clEnqueueCommandBufferKHR((cl_uint) queues.size(),
11089*6fee86a4SJeremy Kemp                 (cl_command_queue *) &queues.front(),
11090*6fee86a4SJeremy Kemp                 object_,
11091*6fee86a4SJeremy Kemp                 (events != nullptr) ? (cl_uint) events->size() : 0,
11092*6fee86a4SJeremy Kemp                 (events != nullptr && events->size() > 0) ? (cl_event*) &events->front() : nullptr,
11093*6fee86a4SJeremy Kemp                 (cl_event*) event),
11094*6fee86a4SJeremy Kemp                 __ENQUEUE_COMMAND_BUFFER_KHR_ERR);
11095*6fee86a4SJeremy Kemp     }
11096*6fee86a4SJeremy Kemp 
commandBarrierWithWaitList(const vector<cl_sync_point_khr> * sync_points_vec=nullptr,cl_sync_point_khr * sync_point=nullptr,MutableCommandKhr * mutable_handle=nullptr,const CommandQueue * command_queue=nullptr)11097*6fee86a4SJeremy Kemp     cl_int commandBarrierWithWaitList(const vector<cl_sync_point_khr>* sync_points_vec = nullptr,
11098*6fee86a4SJeremy Kemp         cl_sync_point_khr* sync_point = nullptr,
11099*6fee86a4SJeremy Kemp         MutableCommandKhr* mutable_handle = nullptr,
11100*6fee86a4SJeremy Kemp         const CommandQueue* command_queue = nullptr)
11101*6fee86a4SJeremy Kemp     {
11102*6fee86a4SJeremy Kemp         if (pfn_clCommandBarrierWithWaitListKHR == nullptr) {
11103*6fee86a4SJeremy Kemp             return detail::errHandler(CL_INVALID_OPERATION,
11104*6fee86a4SJeremy Kemp                     __COMMAND_BARRIER_WITH_WAIT_LIST_KHR_ERR);
11105*6fee86a4SJeremy Kemp         }
11106*6fee86a4SJeremy Kemp 
11107*6fee86a4SJeremy Kemp         cl_sync_point_khr tmp_sync_point;
11108*6fee86a4SJeremy Kemp         cl_int error = detail::errHandler(
11109*6fee86a4SJeremy Kemp             pfn_clCommandBarrierWithWaitListKHR(object_,
11110*6fee86a4SJeremy Kemp                 (command_queue != nullptr) ? (*command_queue)() : nullptr,
11111*6fee86a4SJeremy Kemp                 (sync_points_vec != nullptr) ? (cl_uint) sync_points_vec->size() : 0,
11112*6fee86a4SJeremy Kemp                 (sync_points_vec != nullptr && sync_points_vec->size() > 0) ? &sync_points_vec->front() : nullptr,
11113*6fee86a4SJeremy Kemp                 (sync_point != nullptr) ? &tmp_sync_point : nullptr,
11114*6fee86a4SJeremy Kemp                 (cl_mutable_command_khr*) mutable_handle),
11115*6fee86a4SJeremy Kemp             __COMMAND_BARRIER_WITH_WAIT_LIST_KHR_ERR);
11116*6fee86a4SJeremy Kemp 
11117*6fee86a4SJeremy Kemp         if (sync_point != nullptr && error == CL_SUCCESS)
11118*6fee86a4SJeremy Kemp             *sync_point = tmp_sync_point;
11119*6fee86a4SJeremy Kemp 
11120*6fee86a4SJeremy Kemp         return error;
11121*6fee86a4SJeremy Kemp     }
11122*6fee86a4SJeremy Kemp 
commandCopyBuffer(const Buffer & src,const Buffer & dst,size_type src_offset,size_type dst_offset,size_type size,const vector<cl_sync_point_khr> * sync_points_vec=nullptr,cl_sync_point_khr * sync_point=nullptr,MutableCommandKhr * mutable_handle=nullptr,const CommandQueue * command_queue=nullptr)11123*6fee86a4SJeremy Kemp     cl_int commandCopyBuffer(const Buffer& src,
11124*6fee86a4SJeremy Kemp         const Buffer& dst,
11125*6fee86a4SJeremy Kemp         size_type src_offset,
11126*6fee86a4SJeremy Kemp         size_type dst_offset,
11127*6fee86a4SJeremy Kemp         size_type size,
11128*6fee86a4SJeremy Kemp         const vector<cl_sync_point_khr>* sync_points_vec = nullptr,
11129*6fee86a4SJeremy Kemp         cl_sync_point_khr* sync_point = nullptr,
11130*6fee86a4SJeremy Kemp         MutableCommandKhr* mutable_handle = nullptr,
11131*6fee86a4SJeremy Kemp         const CommandQueue* command_queue = nullptr)
11132*6fee86a4SJeremy Kemp     {
11133*6fee86a4SJeremy Kemp         if (pfn_clCommandCopyBufferKHR == nullptr) {
11134*6fee86a4SJeremy Kemp             return detail::errHandler(CL_INVALID_OPERATION,
11135*6fee86a4SJeremy Kemp                     __COMMAND_COPY_BUFFER_KHR_ERR);
11136*6fee86a4SJeremy Kemp         }
11137*6fee86a4SJeremy Kemp 
11138*6fee86a4SJeremy Kemp         cl_sync_point_khr tmp_sync_point;
11139*6fee86a4SJeremy Kemp         cl_int error = detail::errHandler(
11140*6fee86a4SJeremy Kemp             pfn_clCommandCopyBufferKHR(object_,
11141*6fee86a4SJeremy Kemp                 (command_queue != nullptr) ? (*command_queue)() : nullptr,
11142*6fee86a4SJeremy Kemp                 src(),
11143*6fee86a4SJeremy Kemp                 dst(),
11144*6fee86a4SJeremy Kemp                 src_offset,
11145*6fee86a4SJeremy Kemp                 dst_offset,
11146*6fee86a4SJeremy Kemp                 size,
11147*6fee86a4SJeremy Kemp                 (sync_points_vec != nullptr) ? (cl_uint) sync_points_vec->size() : 0,
11148*6fee86a4SJeremy Kemp                 (sync_points_vec != nullptr && sync_points_vec->size() > 0) ? &sync_points_vec->front() : nullptr,
11149*6fee86a4SJeremy Kemp                 (sync_point != nullptr) ? &tmp_sync_point : nullptr,
11150*6fee86a4SJeremy Kemp                 (cl_mutable_command_khr*) mutable_handle),
11151*6fee86a4SJeremy Kemp             __COMMAND_COPY_BUFFER_KHR_ERR);
11152*6fee86a4SJeremy Kemp 
11153*6fee86a4SJeremy Kemp         if (sync_point != nullptr && error == CL_SUCCESS)
11154*6fee86a4SJeremy Kemp             *sync_point = tmp_sync_point;
11155*6fee86a4SJeremy Kemp 
11156*6fee86a4SJeremy Kemp         return error;
11157*6fee86a4SJeremy Kemp     }
11158*6fee86a4SJeremy Kemp 
commandCopyBufferRect(const Buffer & src,const Buffer & dst,const array<size_type,3> & src_origin,const array<size_type,3> & dst_origin,const array<size_type,3> & region,size_type src_row_pitch,size_type src_slice_pitch,size_type dst_row_pitch,size_type dst_slice_pitch,const vector<cl_sync_point_khr> * sync_points_vec=nullptr,cl_sync_point_khr * sync_point=nullptr,MutableCommandKhr * mutable_handle=nullptr,const CommandQueue * command_queue=nullptr)11159*6fee86a4SJeremy Kemp     cl_int commandCopyBufferRect(const Buffer& src,
11160*6fee86a4SJeremy Kemp         const Buffer& dst,
11161*6fee86a4SJeremy Kemp         const array<size_type, 3>& src_origin,
11162*6fee86a4SJeremy Kemp         const array<size_type, 3>& dst_origin,
11163*6fee86a4SJeremy Kemp         const array<size_type, 3>& region,
11164*6fee86a4SJeremy Kemp         size_type src_row_pitch,
11165*6fee86a4SJeremy Kemp         size_type src_slice_pitch,
11166*6fee86a4SJeremy Kemp         size_type dst_row_pitch,
11167*6fee86a4SJeremy Kemp         size_type dst_slice_pitch,
11168*6fee86a4SJeremy Kemp         const vector<cl_sync_point_khr>* sync_points_vec = nullptr,
11169*6fee86a4SJeremy Kemp         cl_sync_point_khr* sync_point = nullptr,
11170*6fee86a4SJeremy Kemp         MutableCommandKhr* mutable_handle = nullptr,
11171*6fee86a4SJeremy Kemp         const CommandQueue* command_queue = nullptr)
11172*6fee86a4SJeremy Kemp     {
11173*6fee86a4SJeremy Kemp         if (pfn_clCommandCopyBufferRectKHR == nullptr) {
11174*6fee86a4SJeremy Kemp             return detail::errHandler(CL_INVALID_OPERATION,
11175*6fee86a4SJeremy Kemp                     __COMMAND_COPY_BUFFER_RECT_KHR_ERR);
11176*6fee86a4SJeremy Kemp         }
11177*6fee86a4SJeremy Kemp 
11178*6fee86a4SJeremy Kemp         cl_sync_point_khr tmp_sync_point;
11179*6fee86a4SJeremy Kemp         cl_int error = detail::errHandler(
11180*6fee86a4SJeremy Kemp             pfn_clCommandCopyBufferRectKHR(object_,
11181*6fee86a4SJeremy Kemp                 (command_queue != nullptr) ? (*command_queue)() : nullptr,
11182*6fee86a4SJeremy Kemp                 src(),
11183*6fee86a4SJeremy Kemp                 dst(),
11184*6fee86a4SJeremy Kemp                 src_origin.data(),
11185*6fee86a4SJeremy Kemp                 dst_origin.data(),
11186*6fee86a4SJeremy Kemp                 region.data(),
11187*6fee86a4SJeremy Kemp                 src_row_pitch,
11188*6fee86a4SJeremy Kemp                 src_slice_pitch,
11189*6fee86a4SJeremy Kemp                 dst_row_pitch,
11190*6fee86a4SJeremy Kemp                 dst_slice_pitch,
11191*6fee86a4SJeremy Kemp                 (sync_points_vec != nullptr) ? (cl_uint) sync_points_vec->size() : 0,
11192*6fee86a4SJeremy Kemp                 (sync_points_vec != nullptr && sync_points_vec->size() > 0) ? &sync_points_vec->front() : nullptr,
11193*6fee86a4SJeremy Kemp                 (sync_point != nullptr) ? &tmp_sync_point : nullptr,
11194*6fee86a4SJeremy Kemp                 (cl_mutable_command_khr*) mutable_handle),
11195*6fee86a4SJeremy Kemp             __COMMAND_COPY_BUFFER_RECT_KHR_ERR);
11196*6fee86a4SJeremy Kemp 
11197*6fee86a4SJeremy Kemp         if (sync_point != nullptr && error == CL_SUCCESS)
11198*6fee86a4SJeremy Kemp             *sync_point = tmp_sync_point;
11199*6fee86a4SJeremy Kemp 
11200*6fee86a4SJeremy Kemp         return error;
11201*6fee86a4SJeremy Kemp     }
11202*6fee86a4SJeremy Kemp 
commandCopyBufferToImage(const Buffer & src,const Image & dst,size_type src_offset,const array<size_type,3> & dst_origin,const array<size_type,3> & region,const vector<cl_sync_point_khr> * sync_points_vec=nullptr,cl_sync_point_khr * sync_point=nullptr,MutableCommandKhr * mutable_handle=nullptr,const CommandQueue * command_queue=nullptr)11203*6fee86a4SJeremy Kemp     cl_int commandCopyBufferToImage(const Buffer& src,
11204*6fee86a4SJeremy Kemp         const Image& dst,
11205*6fee86a4SJeremy Kemp         size_type src_offset,
11206*6fee86a4SJeremy Kemp         const array<size_type, 3>& dst_origin,
11207*6fee86a4SJeremy Kemp         const array<size_type, 3>& region,
11208*6fee86a4SJeremy Kemp         const vector<cl_sync_point_khr>* sync_points_vec = nullptr,
11209*6fee86a4SJeremy Kemp         cl_sync_point_khr* sync_point = nullptr,
11210*6fee86a4SJeremy Kemp         MutableCommandKhr* mutable_handle = nullptr,
11211*6fee86a4SJeremy Kemp         const CommandQueue* command_queue = nullptr)
11212*6fee86a4SJeremy Kemp     {
11213*6fee86a4SJeremy Kemp         if (pfn_clCommandCopyBufferToImageKHR == nullptr) {
11214*6fee86a4SJeremy Kemp             return detail::errHandler(CL_INVALID_OPERATION,
11215*6fee86a4SJeremy Kemp                     __COMMAND_COPY_BUFFER_TO_IMAGE_KHR_ERR);
11216*6fee86a4SJeremy Kemp         }
11217*6fee86a4SJeremy Kemp 
11218*6fee86a4SJeremy Kemp         cl_sync_point_khr tmp_sync_point;
11219*6fee86a4SJeremy Kemp         cl_int error = detail::errHandler(
11220*6fee86a4SJeremy Kemp             pfn_clCommandCopyBufferToImageKHR(object_,
11221*6fee86a4SJeremy Kemp                 (command_queue != nullptr) ? (*command_queue)() : nullptr,
11222*6fee86a4SJeremy Kemp                 src(),
11223*6fee86a4SJeremy Kemp                 dst(),
11224*6fee86a4SJeremy Kemp                 src_offset,
11225*6fee86a4SJeremy Kemp                 dst_origin.data(),
11226*6fee86a4SJeremy Kemp                 region.data(),
11227*6fee86a4SJeremy Kemp                 (sync_points_vec != nullptr) ? (cl_uint) sync_points_vec->size() : 0,
11228*6fee86a4SJeremy Kemp                 (sync_points_vec != nullptr && sync_points_vec->size() > 0) ? &sync_points_vec->front() : nullptr,
11229*6fee86a4SJeremy Kemp                 (sync_point != nullptr) ? &tmp_sync_point : nullptr,
11230*6fee86a4SJeremy Kemp                 (cl_mutable_command_khr*) mutable_handle),
11231*6fee86a4SJeremy Kemp             __COMMAND_COPY_BUFFER_TO_IMAGE_KHR_ERR);
11232*6fee86a4SJeremy Kemp 
11233*6fee86a4SJeremy Kemp         if (sync_point != nullptr && error == CL_SUCCESS)
11234*6fee86a4SJeremy Kemp             *sync_point = tmp_sync_point;
11235*6fee86a4SJeremy Kemp 
11236*6fee86a4SJeremy Kemp         return error;
11237*6fee86a4SJeremy Kemp     }
11238*6fee86a4SJeremy Kemp 
commandCopyImage(const Image & src,const Image & dst,const array<size_type,3> & src_origin,const array<size_type,3> & dst_origin,const array<size_type,3> & region,const vector<cl_sync_point_khr> * sync_points_vec=nullptr,cl_sync_point_khr * sync_point=nullptr,MutableCommandKhr * mutable_handle=nullptr,const CommandQueue * command_queue=nullptr)11239*6fee86a4SJeremy Kemp     cl_int commandCopyImage(const Image& src,
11240*6fee86a4SJeremy Kemp         const Image& dst,
11241*6fee86a4SJeremy Kemp         const array<size_type, 3>& src_origin,
11242*6fee86a4SJeremy Kemp         const array<size_type, 3>& dst_origin,
11243*6fee86a4SJeremy Kemp         const array<size_type, 3>& region,
11244*6fee86a4SJeremy Kemp         const vector<cl_sync_point_khr>* sync_points_vec = nullptr,
11245*6fee86a4SJeremy Kemp         cl_sync_point_khr* sync_point = nullptr,
11246*6fee86a4SJeremy Kemp         MutableCommandKhr* mutable_handle = nullptr,
11247*6fee86a4SJeremy Kemp         const CommandQueue* command_queue = nullptr)
11248*6fee86a4SJeremy Kemp     {
11249*6fee86a4SJeremy Kemp         if (pfn_clCommandCopyImageKHR == nullptr) {
11250*6fee86a4SJeremy Kemp             return detail::errHandler(CL_INVALID_OPERATION,
11251*6fee86a4SJeremy Kemp                     __COMMAND_COPY_IMAGE_KHR_ERR);
11252*6fee86a4SJeremy Kemp         }
11253*6fee86a4SJeremy Kemp 
11254*6fee86a4SJeremy Kemp         cl_sync_point_khr tmp_sync_point;
11255*6fee86a4SJeremy Kemp         cl_int error = detail::errHandler(
11256*6fee86a4SJeremy Kemp             pfn_clCommandCopyImageKHR(object_,
11257*6fee86a4SJeremy Kemp                 (command_queue != nullptr) ? (*command_queue)() : nullptr,
11258*6fee86a4SJeremy Kemp                 src(),
11259*6fee86a4SJeremy Kemp                 dst(),
11260*6fee86a4SJeremy Kemp                 src_origin.data(),
11261*6fee86a4SJeremy Kemp                 dst_origin.data(),
11262*6fee86a4SJeremy Kemp                 region.data(),
11263*6fee86a4SJeremy Kemp                 (sync_points_vec != nullptr) ? (cl_uint) sync_points_vec->size() : 0,
11264*6fee86a4SJeremy Kemp                 (sync_points_vec != nullptr && sync_points_vec->size() > 0) ? &sync_points_vec->front() : nullptr,
11265*6fee86a4SJeremy Kemp                 (sync_point != nullptr) ? &tmp_sync_point : nullptr,
11266*6fee86a4SJeremy Kemp                 (cl_mutable_command_khr*) mutable_handle),
11267*6fee86a4SJeremy Kemp             __COMMAND_COPY_IMAGE_KHR_ERR);
11268*6fee86a4SJeremy Kemp 
11269*6fee86a4SJeremy Kemp         if (sync_point != nullptr && error == CL_SUCCESS)
11270*6fee86a4SJeremy Kemp             *sync_point = tmp_sync_point;
11271*6fee86a4SJeremy Kemp 
11272*6fee86a4SJeremy Kemp         return error;
11273*6fee86a4SJeremy Kemp     }
11274*6fee86a4SJeremy Kemp 
commandCopyImageToBuffer(const Image & src,const Buffer & dst,const array<size_type,3> & src_origin,const array<size_type,3> & region,size_type dst_offset,const vector<cl_sync_point_khr> * sync_points_vec=nullptr,cl_sync_point_khr * sync_point=nullptr,MutableCommandKhr * mutable_handle=nullptr,const CommandQueue * command_queue=nullptr)11275*6fee86a4SJeremy Kemp     cl_int commandCopyImageToBuffer(const Image& src,
11276*6fee86a4SJeremy Kemp         const Buffer& dst,
11277*6fee86a4SJeremy Kemp         const array<size_type, 3>& src_origin,
11278*6fee86a4SJeremy Kemp         const array<size_type, 3>& region,
11279*6fee86a4SJeremy Kemp         size_type dst_offset,
11280*6fee86a4SJeremy Kemp         const vector<cl_sync_point_khr>* sync_points_vec = nullptr,
11281*6fee86a4SJeremy Kemp         cl_sync_point_khr* sync_point = nullptr,
11282*6fee86a4SJeremy Kemp         MutableCommandKhr* mutable_handle = nullptr,
11283*6fee86a4SJeremy Kemp         const CommandQueue* command_queue = nullptr)
11284*6fee86a4SJeremy Kemp     {
11285*6fee86a4SJeremy Kemp         if (pfn_clCommandCopyImageToBufferKHR == nullptr) {
11286*6fee86a4SJeremy Kemp             return detail::errHandler(CL_INVALID_OPERATION,
11287*6fee86a4SJeremy Kemp                     __COMMAND_COPY_IMAGE_TO_BUFFER_KHR_ERR);
11288*6fee86a4SJeremy Kemp         }
11289*6fee86a4SJeremy Kemp 
11290*6fee86a4SJeremy Kemp         cl_sync_point_khr tmp_sync_point;
11291*6fee86a4SJeremy Kemp         cl_int error = detail::errHandler(
11292*6fee86a4SJeremy Kemp             pfn_clCommandCopyImageToBufferKHR(object_,
11293*6fee86a4SJeremy Kemp                 (command_queue != nullptr) ? (*command_queue)() : nullptr,
11294*6fee86a4SJeremy Kemp                 src(),
11295*6fee86a4SJeremy Kemp                 dst(),
11296*6fee86a4SJeremy Kemp                 src_origin.data(),
11297*6fee86a4SJeremy Kemp                 region.data(),
11298*6fee86a4SJeremy Kemp                 dst_offset,
11299*6fee86a4SJeremy Kemp                 (sync_points_vec != nullptr) ? (cl_uint) sync_points_vec->size() : 0,
11300*6fee86a4SJeremy Kemp                 (sync_points_vec != nullptr && sync_points_vec->size() > 0) ? &sync_points_vec->front() : nullptr,
11301*6fee86a4SJeremy Kemp                 (sync_point != nullptr) ? &tmp_sync_point : nullptr,
11302*6fee86a4SJeremy Kemp                 (cl_mutable_command_khr*) mutable_handle),
11303*6fee86a4SJeremy Kemp             __COMMAND_COPY_IMAGE_TO_BUFFER_KHR_ERR);
11304*6fee86a4SJeremy Kemp 
11305*6fee86a4SJeremy Kemp         if (sync_point != nullptr && error == CL_SUCCESS)
11306*6fee86a4SJeremy Kemp             *sync_point = tmp_sync_point;
11307*6fee86a4SJeremy Kemp 
11308*6fee86a4SJeremy Kemp         return error;
11309*6fee86a4SJeremy Kemp     }
11310*6fee86a4SJeremy Kemp 
11311*6fee86a4SJeremy Kemp     template<typename PatternType>
commandFillBuffer(const Buffer & buffer,PatternType pattern,size_type offset,size_type size,const vector<cl_sync_point_khr> * sync_points_vec=nullptr,cl_sync_point_khr * sync_point=nullptr,MutableCommandKhr * mutable_handle=nullptr,const CommandQueue * command_queue=nullptr)11312*6fee86a4SJeremy Kemp     cl_int commandFillBuffer(const Buffer& buffer,
11313*6fee86a4SJeremy Kemp         PatternType pattern,
11314*6fee86a4SJeremy Kemp         size_type offset,
11315*6fee86a4SJeremy Kemp         size_type size,
11316*6fee86a4SJeremy Kemp         const vector<cl_sync_point_khr>* sync_points_vec = nullptr,
11317*6fee86a4SJeremy Kemp         cl_sync_point_khr* sync_point = nullptr,
11318*6fee86a4SJeremy Kemp         MutableCommandKhr* mutable_handle = nullptr,
11319*6fee86a4SJeremy Kemp         const CommandQueue* command_queue = nullptr)
11320*6fee86a4SJeremy Kemp     {
11321*6fee86a4SJeremy Kemp         if (pfn_clCommandFillBufferKHR == nullptr) {
11322*6fee86a4SJeremy Kemp             return detail::errHandler(CL_INVALID_OPERATION,
11323*6fee86a4SJeremy Kemp                     __COMMAND_FILL_BUFFER_KHR_ERR);
11324*6fee86a4SJeremy Kemp         }
11325*6fee86a4SJeremy Kemp 
11326*6fee86a4SJeremy Kemp         cl_sync_point_khr tmp_sync_point;
11327*6fee86a4SJeremy Kemp         cl_int error = detail::errHandler(
11328*6fee86a4SJeremy Kemp             pfn_clCommandFillBufferKHR(object_,
11329*6fee86a4SJeremy Kemp                 (command_queue != nullptr) ? (*command_queue)() : nullptr,
11330*6fee86a4SJeremy Kemp                 buffer(),
11331*6fee86a4SJeremy Kemp                 static_cast<void*>(&pattern),
11332*6fee86a4SJeremy Kemp                 sizeof(PatternType),
11333*6fee86a4SJeremy Kemp                 offset,
11334*6fee86a4SJeremy Kemp                 size,
11335*6fee86a4SJeremy Kemp                 (sync_points_vec != nullptr) ? (cl_uint) sync_points_vec->size() : 0,
11336*6fee86a4SJeremy Kemp                 (sync_points_vec != nullptr && sync_points_vec->size() > 0) ? &sync_points_vec->front() : nullptr,
11337*6fee86a4SJeremy Kemp                 (sync_point != nullptr) ? &tmp_sync_point : nullptr,
11338*6fee86a4SJeremy Kemp                 (cl_mutable_command_khr*) mutable_handle),
11339*6fee86a4SJeremy Kemp             __COMMAND_FILL_BUFFER_KHR_ERR);
11340*6fee86a4SJeremy Kemp 
11341*6fee86a4SJeremy Kemp         if (sync_point != nullptr && error == CL_SUCCESS)
11342*6fee86a4SJeremy Kemp             *sync_point = tmp_sync_point;
11343*6fee86a4SJeremy Kemp 
11344*6fee86a4SJeremy Kemp         return error;
11345*6fee86a4SJeremy Kemp     }
11346*6fee86a4SJeremy Kemp 
commandFillImage(const Image & image,cl_float4 fillColor,const array<size_type,3> & origin,const array<size_type,3> & region,const vector<cl_sync_point_khr> * sync_points_vec=nullptr,cl_sync_point_khr * sync_point=nullptr,MutableCommandKhr * mutable_handle=nullptr,const CommandQueue * command_queue=nullptr)11347*6fee86a4SJeremy Kemp     cl_int commandFillImage(const Image& image,
11348*6fee86a4SJeremy Kemp         cl_float4 fillColor,
11349*6fee86a4SJeremy Kemp         const array<size_type, 3>& origin,
11350*6fee86a4SJeremy Kemp         const array<size_type, 3>& region,
11351*6fee86a4SJeremy Kemp         const vector<cl_sync_point_khr>* sync_points_vec = nullptr,
11352*6fee86a4SJeremy Kemp         cl_sync_point_khr* sync_point = nullptr,
11353*6fee86a4SJeremy Kemp         MutableCommandKhr* mutable_handle = nullptr,
11354*6fee86a4SJeremy Kemp         const CommandQueue* command_queue = nullptr)
11355*6fee86a4SJeremy Kemp     {
11356*6fee86a4SJeremy Kemp         if (pfn_clCommandFillImageKHR == nullptr) {
11357*6fee86a4SJeremy Kemp             return detail::errHandler(CL_INVALID_OPERATION,
11358*6fee86a4SJeremy Kemp                     __COMMAND_FILL_IMAGE_KHR_ERR);
11359*6fee86a4SJeremy Kemp         }
11360*6fee86a4SJeremy Kemp 
11361*6fee86a4SJeremy Kemp         cl_sync_point_khr tmp_sync_point;
11362*6fee86a4SJeremy Kemp         cl_int error = detail::errHandler(
11363*6fee86a4SJeremy Kemp             pfn_clCommandFillImageKHR(object_,
11364*6fee86a4SJeremy Kemp                 (command_queue != nullptr) ? (*command_queue)() : nullptr,
11365*6fee86a4SJeremy Kemp                 image(),
11366*6fee86a4SJeremy Kemp                 static_cast<void*>(&fillColor),
11367*6fee86a4SJeremy Kemp                 origin.data(),
11368*6fee86a4SJeremy Kemp                 region.data(),
11369*6fee86a4SJeremy Kemp                 (sync_points_vec != nullptr) ? (cl_uint) sync_points_vec->size() : 0,
11370*6fee86a4SJeremy Kemp                 (sync_points_vec != nullptr && sync_points_vec->size() > 0) ? &sync_points_vec->front() : nullptr,
11371*6fee86a4SJeremy Kemp                 (sync_point != nullptr) ? &tmp_sync_point : nullptr,
11372*6fee86a4SJeremy Kemp                 (cl_mutable_command_khr*) mutable_handle),
11373*6fee86a4SJeremy Kemp             __COMMAND_FILL_IMAGE_KHR_ERR);
11374*6fee86a4SJeremy Kemp 
11375*6fee86a4SJeremy Kemp         if (sync_point != nullptr && error == CL_SUCCESS)
11376*6fee86a4SJeremy Kemp             *sync_point = tmp_sync_point;
11377*6fee86a4SJeremy Kemp 
11378*6fee86a4SJeremy Kemp         return error;
11379*6fee86a4SJeremy Kemp     }
11380*6fee86a4SJeremy Kemp 
commandNDRangeKernel(const cl::vector<cl_ndrange_kernel_command_properties_khr> & properties,const Kernel & kernel,const NDRange & offset,const NDRange & global,const NDRange & local=NullRange,const vector<cl_sync_point_khr> * sync_points_vec=nullptr,cl_sync_point_khr * sync_point=nullptr,MutableCommandKhr * mutable_handle=nullptr,const CommandQueue * command_queue=nullptr)11381*6fee86a4SJeremy Kemp     cl_int commandNDRangeKernel(const cl::vector<cl_ndrange_kernel_command_properties_khr> &properties,
11382*6fee86a4SJeremy Kemp         const Kernel& kernel,
11383*6fee86a4SJeremy Kemp         const NDRange& offset,
11384*6fee86a4SJeremy Kemp         const NDRange& global,
11385*6fee86a4SJeremy Kemp         const NDRange& local = NullRange,
11386*6fee86a4SJeremy Kemp         const vector<cl_sync_point_khr>* sync_points_vec = nullptr,
11387*6fee86a4SJeremy Kemp         cl_sync_point_khr* sync_point = nullptr,
11388*6fee86a4SJeremy Kemp         MutableCommandKhr* mutable_handle = nullptr,
11389*6fee86a4SJeremy Kemp         const CommandQueue* command_queue = nullptr)
11390*6fee86a4SJeremy Kemp     {
11391*6fee86a4SJeremy Kemp         if (pfn_clCommandNDRangeKernelKHR == nullptr) {
11392*6fee86a4SJeremy Kemp             return detail::errHandler(CL_INVALID_OPERATION,
11393*6fee86a4SJeremy Kemp                     __COMMAND_NDRANGE_KERNEL_KHR_ERR);
11394*6fee86a4SJeremy Kemp         }
11395*6fee86a4SJeremy Kemp 
11396*6fee86a4SJeremy Kemp         cl_sync_point_khr tmp_sync_point;
11397*6fee86a4SJeremy Kemp         cl_int error = detail::errHandler(
11398*6fee86a4SJeremy Kemp             pfn_clCommandNDRangeKernelKHR(object_,
11399*6fee86a4SJeremy Kemp                 (command_queue != nullptr) ? (*command_queue)() : nullptr,
11400*6fee86a4SJeremy Kemp                 &properties[0],
11401*6fee86a4SJeremy Kemp                 kernel(),
11402*6fee86a4SJeremy Kemp                 (cl_uint) global.dimensions(),
11403*6fee86a4SJeremy Kemp                 offset.dimensions() != 0 ? (const size_type*) offset : nullptr,
11404*6fee86a4SJeremy Kemp                 (const size_type*) global,
11405*6fee86a4SJeremy Kemp                 local.dimensions() != 0 ? (const size_type*) local : nullptr,
11406*6fee86a4SJeremy Kemp                 (sync_points_vec != nullptr) ? (cl_uint) sync_points_vec->size() : 0,
11407*6fee86a4SJeremy Kemp                 (sync_points_vec != nullptr && sync_points_vec->size() > 0) ? &sync_points_vec->front() : nullptr,
11408*6fee86a4SJeremy Kemp                 (sync_point != nullptr) ? &tmp_sync_point : nullptr,
11409*6fee86a4SJeremy Kemp                 (cl_mutable_command_khr*) mutable_handle),
11410*6fee86a4SJeremy Kemp             __COMMAND_NDRANGE_KERNEL_KHR_ERR);
11411*6fee86a4SJeremy Kemp 
11412*6fee86a4SJeremy Kemp         if (sync_point != nullptr && error == CL_SUCCESS)
11413*6fee86a4SJeremy Kemp             *sync_point = tmp_sync_point;
11414*6fee86a4SJeremy Kemp 
11415*6fee86a4SJeremy Kemp         return error;
11416*6fee86a4SJeremy Kemp     }
11417*6fee86a4SJeremy Kemp 
11418*6fee86a4SJeremy Kemp #if defined(cl_khr_command_buffer_mutable_dispatch)
updateMutableCommands(const cl_mutable_base_config_khr * mutable_config)11419*6fee86a4SJeremy Kemp     cl_int updateMutableCommands(const cl_mutable_base_config_khr* mutable_config)
11420*6fee86a4SJeremy Kemp     {
11421*6fee86a4SJeremy Kemp         if (pfn_clUpdateMutableCommandsKHR == nullptr) {
11422*6fee86a4SJeremy Kemp             return detail::errHandler(CL_INVALID_OPERATION,
11423*6fee86a4SJeremy Kemp                     __UPDATE_MUTABLE_COMMANDS_KHR_ERR);
11424*6fee86a4SJeremy Kemp         }
11425*6fee86a4SJeremy Kemp         return detail::errHandler(pfn_clUpdateMutableCommandsKHR(object_, mutable_config),
11426*6fee86a4SJeremy Kemp                         __UPDATE_MUTABLE_COMMANDS_KHR_ERR);
11427*6fee86a4SJeremy Kemp     }
11428*6fee86a4SJeremy Kemp #endif /* cl_khr_command_buffer_mutable_dispatch */
11429*6fee86a4SJeremy Kemp 
11430*6fee86a4SJeremy Kemp private:
11431*6fee86a4SJeremy Kemp     static std::once_flag ext_init_;
11432*6fee86a4SJeremy Kemp 
initExtensions(const cl::Device & device)11433*6fee86a4SJeremy Kemp     static void initExtensions(const cl::Device& device)
11434*6fee86a4SJeremy Kemp     {
11435*6fee86a4SJeremy Kemp #if CL_HPP_TARGET_OPENCL_VERSION >= 120
11436*6fee86a4SJeremy Kemp         cl_platform_id platform = device.getInfo<CL_DEVICE_PLATFORM>()();
11437*6fee86a4SJeremy Kemp         CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clCreateCommandBufferKHR);
11438*6fee86a4SJeremy Kemp         CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clFinalizeCommandBufferKHR);
11439*6fee86a4SJeremy Kemp         CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clRetainCommandBufferKHR);
11440*6fee86a4SJeremy Kemp         CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clReleaseCommandBufferKHR);
11441*6fee86a4SJeremy Kemp         CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clGetCommandBufferInfoKHR);
11442*6fee86a4SJeremy Kemp         CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clEnqueueCommandBufferKHR);
11443*6fee86a4SJeremy Kemp         CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clCommandBarrierWithWaitListKHR);
11444*6fee86a4SJeremy Kemp         CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clCommandCopyBufferKHR);
11445*6fee86a4SJeremy Kemp         CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clCommandCopyBufferRectKHR);
11446*6fee86a4SJeremy Kemp         CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clCommandCopyBufferToImageKHR);
11447*6fee86a4SJeremy Kemp         CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clCommandCopyImageKHR);
11448*6fee86a4SJeremy Kemp         CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clCommandCopyImageToBufferKHR);
11449*6fee86a4SJeremy Kemp         CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clCommandFillBufferKHR);
11450*6fee86a4SJeremy Kemp         CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clCommandFillImageKHR);
11451*6fee86a4SJeremy Kemp         CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clCommandNDRangeKernelKHR);
11452*6fee86a4SJeremy Kemp #if defined(cl_khr_command_buffer_mutable_dispatch)
11453*6fee86a4SJeremy Kemp         CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clUpdateMutableCommandsKHR);
11454*6fee86a4SJeremy Kemp         CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_(platform, clGetMutableCommandInfoKHR);
11455*6fee86a4SJeremy Kemp #endif /* cl_khr_command_buffer_mutable_dispatch */
11456*6fee86a4SJeremy Kemp #elif CL_HPP_TARGET_OPENCL_VERSION >= 110
11457*6fee86a4SJeremy Kemp         CL_HPP_INIT_CL_EXT_FCN_PTR_(clCreateCommandBufferKHR);
11458*6fee86a4SJeremy Kemp         CL_HPP_INIT_CL_EXT_FCN_PTR_(clFinalizeCommandBufferKHR);
11459*6fee86a4SJeremy Kemp         CL_HPP_INIT_CL_EXT_FCN_PTR_(clRetainCommandBufferKHR);
11460*6fee86a4SJeremy Kemp         CL_HPP_INIT_CL_EXT_FCN_PTR_(clReleaseCommandBufferKHR);
11461*6fee86a4SJeremy Kemp         CL_HPP_INIT_CL_EXT_FCN_PTR_(clGetCommandBufferInfoKHR);
11462*6fee86a4SJeremy Kemp         CL_HPP_INIT_CL_EXT_FCN_PTR_(clEnqueueCommandBufferKHR);
11463*6fee86a4SJeremy Kemp         CL_HPP_INIT_CL_EXT_FCN_PTR_(clCommandBarrierWithWaitListKHR);
11464*6fee86a4SJeremy Kemp         CL_HPP_INIT_CL_EXT_FCN_PTR_(clCommandCopyBufferKHR);
11465*6fee86a4SJeremy Kemp         CL_HPP_INIT_CL_EXT_FCN_PTR_(clCommandCopyBufferRectKHR);
11466*6fee86a4SJeremy Kemp         CL_HPP_INIT_CL_EXT_FCN_PTR_(clCommandCopyBufferToImageKHR);
11467*6fee86a4SJeremy Kemp         CL_HPP_INIT_CL_EXT_FCN_PTR_(clCommandCopyImageKHR);
11468*6fee86a4SJeremy Kemp         CL_HPP_INIT_CL_EXT_FCN_PTR_(clCommandCopyImageToBufferKHR);
11469*6fee86a4SJeremy Kemp         CL_HPP_INIT_CL_EXT_FCN_PTR_(clCommandFillBufferKHR);
11470*6fee86a4SJeremy Kemp         CL_HPP_INIT_CL_EXT_FCN_PTR_(clCommandFillImageKHR);
11471*6fee86a4SJeremy Kemp         CL_HPP_INIT_CL_EXT_FCN_PTR_(clCommandNDRangeKernelKHR);
11472*6fee86a4SJeremy Kemp #if defined(cl_khr_command_buffer_mutable_dispatch)
11473*6fee86a4SJeremy Kemp         CL_HPP_INIT_CL_EXT_FCN_PTR_(clUpdateMutableCommandsKHR);
11474*6fee86a4SJeremy Kemp         CL_HPP_INIT_CL_EXT_FCN_PTR_(clGetMutableCommandInfoKHR);
11475*6fee86a4SJeremy Kemp #endif /* cl_khr_command_buffer_mutable_dispatch */
11476*6fee86a4SJeremy Kemp #endif
11477*6fee86a4SJeremy Kemp         if ((pfn_clCreateCommandBufferKHR        == nullptr) &&
11478*6fee86a4SJeremy Kemp             (pfn_clFinalizeCommandBufferKHR      == nullptr) &&
11479*6fee86a4SJeremy Kemp             (pfn_clRetainCommandBufferKHR        == nullptr) &&
11480*6fee86a4SJeremy Kemp             (pfn_clReleaseCommandBufferKHR       == nullptr) &&
11481*6fee86a4SJeremy Kemp             (pfn_clGetCommandBufferInfoKHR       == nullptr) &&
11482*6fee86a4SJeremy Kemp             (pfn_clEnqueueCommandBufferKHR       == nullptr) &&
11483*6fee86a4SJeremy Kemp             (pfn_clCommandBarrierWithWaitListKHR == nullptr) &&
11484*6fee86a4SJeremy Kemp             (pfn_clCommandCopyBufferKHR          == nullptr) &&
11485*6fee86a4SJeremy Kemp             (pfn_clCommandCopyBufferRectKHR      == nullptr) &&
11486*6fee86a4SJeremy Kemp             (pfn_clCommandCopyBufferToImageKHR   == nullptr) &&
11487*6fee86a4SJeremy Kemp             (pfn_clCommandCopyImageKHR           == nullptr) &&
11488*6fee86a4SJeremy Kemp             (pfn_clCommandCopyImageToBufferKHR   == nullptr) &&
11489*6fee86a4SJeremy Kemp             (pfn_clCommandFillBufferKHR          == nullptr) &&
11490*6fee86a4SJeremy Kemp             (pfn_clCommandFillImageKHR           == nullptr) &&
11491*6fee86a4SJeremy Kemp             (pfn_clCommandNDRangeKernelKHR       == nullptr)
11492*6fee86a4SJeremy Kemp #if defined(cl_khr_command_buffer_mutable_dispatch)
11493*6fee86a4SJeremy Kemp             && (pfn_clUpdateMutableCommandsKHR      == nullptr)
11494*6fee86a4SJeremy Kemp             && (pfn_clGetMutableCommandInfoKHR      == nullptr)
11495*6fee86a4SJeremy Kemp #endif /* cl_khr_command_buffer_mutable_dispatch */
11496*6fee86a4SJeremy Kemp             )
11497*6fee86a4SJeremy Kemp         {
11498*6fee86a4SJeremy Kemp             detail::errHandler(CL_INVALID_VALUE, __CREATE_COMMAND_BUFFER_KHR_ERR);
11499*6fee86a4SJeremy Kemp         }
11500*6fee86a4SJeremy Kemp     }
11501*6fee86a4SJeremy Kemp }; // CommandBufferKhr
11502*6fee86a4SJeremy Kemp 
11503*6fee86a4SJeremy Kemp CL_HPP_DEFINE_STATIC_MEMBER_ std::once_flag CommandBufferKhr::ext_init_;
11504*6fee86a4SJeremy Kemp 
11505*6fee86a4SJeremy Kemp #if defined(cl_khr_command_buffer_mutable_dispatch)
11506*6fee86a4SJeremy Kemp /*! \class MutableCommandKhr
11507*6fee86a4SJeremy Kemp  * \brief MutableCommandKhr interface for cl_mutable_command_khr.
11508*6fee86a4SJeremy Kemp  */
11509*6fee86a4SJeremy Kemp class MutableCommandKhr : public detail::Wrapper<cl_mutable_command_khr>
11510*6fee86a4SJeremy Kemp {
11511*6fee86a4SJeremy Kemp public:
11512*6fee86a4SJeremy Kemp     //! \brief Default constructor - initializes to nullptr.
MutableCommandKhr()11513*6fee86a4SJeremy Kemp     MutableCommandKhr() : detail::Wrapper<cl_type>() { }
11514*6fee86a4SJeremy Kemp 
MutableCommandKhr(const cl_mutable_command_khr & mutableCommandKhr,bool retainObject=false)11515*6fee86a4SJeremy Kemp     explicit MutableCommandKhr(const cl_mutable_command_khr& mutableCommandKhr, bool retainObject = false) :
11516*6fee86a4SJeremy Kemp         detail::Wrapper<cl_type>(mutableCommandKhr, retainObject) { }
11517*6fee86a4SJeremy Kemp 
operator =(const cl_mutable_command_khr & rhs)11518*6fee86a4SJeremy Kemp     MutableCommandKhr& operator=(const cl_mutable_command_khr& rhs)
11519*6fee86a4SJeremy Kemp     {
11520*6fee86a4SJeremy Kemp         detail::Wrapper<cl_type>::operator=(rhs);
11521*6fee86a4SJeremy Kemp         return *this;
11522*6fee86a4SJeremy Kemp     }
11523*6fee86a4SJeremy Kemp 
11524*6fee86a4SJeremy Kemp     template <typename T>
getInfo(cl_mutable_command_info_khr name,T * param) const11525*6fee86a4SJeremy Kemp     cl_int getInfo(cl_mutable_command_info_khr name, T* param) const
11526*6fee86a4SJeremy Kemp     {
11527*6fee86a4SJeremy Kemp         if (pfn_clGetMutableCommandInfoKHR == nullptr) {
11528*6fee86a4SJeremy Kemp             return detail::errHandler(CL_INVALID_OPERATION,
11529*6fee86a4SJeremy Kemp                     __GET_MUTABLE_COMMAND_INFO_KHR_ERR);
11530*6fee86a4SJeremy Kemp         }
11531*6fee86a4SJeremy Kemp         return detail::errHandler(
11532*6fee86a4SJeremy Kemp             detail::getInfo(pfn_clGetMutableCommandInfoKHR, object_, name, param),
11533*6fee86a4SJeremy Kemp                 __GET_MUTABLE_COMMAND_INFO_KHR_ERR);
11534*6fee86a4SJeremy Kemp     }
11535*6fee86a4SJeremy Kemp 
11536*6fee86a4SJeremy Kemp     template <cl_mutable_command_info_khr name> typename
11537*6fee86a4SJeremy Kemp         detail::param_traits<detail::cl_mutable_command_info_khr, name>::param_type
getInfo(cl_int * err=nullptr) const11538*6fee86a4SJeremy Kemp         getInfo(cl_int* err = nullptr) const
11539*6fee86a4SJeremy Kemp     {
11540*6fee86a4SJeremy Kemp         typename detail::param_traits<
11541*6fee86a4SJeremy Kemp             detail::cl_mutable_command_info_khr, name>::param_type param;
11542*6fee86a4SJeremy Kemp         cl_int result = getInfo(name, &param);
11543*6fee86a4SJeremy Kemp         if (err != nullptr) {
11544*6fee86a4SJeremy Kemp             *err = result;
11545*6fee86a4SJeremy Kemp         }
11546*6fee86a4SJeremy Kemp         return param;
11547*6fee86a4SJeremy Kemp     }
11548*6fee86a4SJeremy Kemp }; // MutableCommandKhr
11549*6fee86a4SJeremy Kemp #endif /* cl_khr_command_buffer_mutable_dispatch */
11550*6fee86a4SJeremy Kemp 
11551*6fee86a4SJeremy Kemp #endif // cl_khr_command_buffer
11552*6fee86a4SJeremy Kemp //----------------------------------------------------------------------------------------------------------------------
11553*6fee86a4SJeremy Kemp 
11554*6fee86a4SJeremy Kemp #undef CL_HPP_ERR_STR_
11555*6fee86a4SJeremy Kemp #if !defined(CL_HPP_USER_OVERRIDE_ERROR_STRINGS)
11556*6fee86a4SJeremy Kemp #undef __GET_DEVICE_INFO_ERR
11557*6fee86a4SJeremy Kemp #undef __GET_PLATFORM_INFO_ERR
11558*6fee86a4SJeremy Kemp #undef __GET_DEVICE_IDS_ERR
11559*6fee86a4SJeremy Kemp #undef __GET_PLATFORM_IDS_ERR
11560*6fee86a4SJeremy Kemp #undef __GET_CONTEXT_INFO_ERR
11561*6fee86a4SJeremy Kemp #undef __GET_EVENT_INFO_ERR
11562*6fee86a4SJeremy Kemp #undef __GET_EVENT_PROFILE_INFO_ERR
11563*6fee86a4SJeremy Kemp #undef __GET_MEM_OBJECT_INFO_ERR
11564*6fee86a4SJeremy Kemp #undef __GET_IMAGE_INFO_ERR
11565*6fee86a4SJeremy Kemp #undef __GET_SAMPLER_INFO_ERR
11566*6fee86a4SJeremy Kemp #undef __GET_KERNEL_INFO_ERR
11567*6fee86a4SJeremy Kemp #undef __GET_KERNEL_ARG_INFO_ERR
11568*6fee86a4SJeremy Kemp #undef __GET_KERNEL_SUB_GROUP_INFO_ERR
11569*6fee86a4SJeremy Kemp #undef __GET_KERNEL_WORK_GROUP_INFO_ERR
11570*6fee86a4SJeremy Kemp #undef __GET_PROGRAM_INFO_ERR
11571*6fee86a4SJeremy Kemp #undef __GET_PROGRAM_BUILD_INFO_ERR
11572*6fee86a4SJeremy Kemp #undef __GET_COMMAND_QUEUE_INFO_ERR
11573*6fee86a4SJeremy Kemp #undef __CREATE_CONTEXT_ERR
11574*6fee86a4SJeremy Kemp #undef __CREATE_CONTEXT_FROM_TYPE_ERR
11575*6fee86a4SJeremy Kemp #undef __CREATE_COMMAND_BUFFER_KHR_ERR
11576*6fee86a4SJeremy Kemp #undef __GET_COMMAND_BUFFER_INFO_KHR_ERR
11577*6fee86a4SJeremy Kemp #undef __FINALIZE_COMMAND_BUFFER_KHR_ERR
11578*6fee86a4SJeremy Kemp #undef __ENQUEUE_COMMAND_BUFFER_KHR_ERR
11579*6fee86a4SJeremy Kemp #undef __COMMAND_BARRIER_WITH_WAIT_LIST_KHR_ERR
11580*6fee86a4SJeremy Kemp #undef __COMMAND_COPY_BUFFER_KHR_ERR
11581*6fee86a4SJeremy Kemp #undef __COMMAND_COPY_BUFFER_RECT_KHR_ERR
11582*6fee86a4SJeremy Kemp #undef __COMMAND_COPY_BUFFER_TO_IMAGE_KHR_ERR
11583*6fee86a4SJeremy Kemp #undef __COMMAND_COPY_IMAGE_KHR_ERR
11584*6fee86a4SJeremy Kemp #undef __COMMAND_COPY_IMAGE_TO_BUFFER_KHR_ERR
11585*6fee86a4SJeremy Kemp #undef __COMMAND_FILL_BUFFER_KHR_ERR
11586*6fee86a4SJeremy Kemp #undef __COMMAND_FILL_IMAGE_KHR_ERR
11587*6fee86a4SJeremy Kemp #undef __COMMAND_NDRANGE_KERNEL_KHR_ERR
11588*6fee86a4SJeremy Kemp #undef __UPDATE_MUTABLE_COMMANDS_KHR_ERR
11589*6fee86a4SJeremy Kemp #undef __GET_MUTABLE_COMMAND_INFO_KHR_ERR
11590*6fee86a4SJeremy Kemp #undef __RETAIN_COMMAND_BUFFER_KHR_ERR
11591*6fee86a4SJeremy Kemp #undef __RELEASE_COMMAND_BUFFER_KHR_ERR
11592*6fee86a4SJeremy Kemp #undef __GET_SUPPORTED_IMAGE_FORMATS_ERR
11593*6fee86a4SJeremy Kemp #undef __SET_CONTEXT_DESCTRUCTOR_CALLBACK_ERR
11594*6fee86a4SJeremy Kemp #undef __CREATE_BUFFER_ERR
11595*6fee86a4SJeremy Kemp #undef __COPY_ERR
11596*6fee86a4SJeremy Kemp #undef __CREATE_SUBBUFFER_ERR
11597*6fee86a4SJeremy Kemp #undef __CREATE_GL_BUFFER_ERR
11598*6fee86a4SJeremy Kemp #undef __CREATE_GL_RENDER_BUFFER_ERR
11599*6fee86a4SJeremy Kemp #undef __GET_GL_OBJECT_INFO_ERR
11600*6fee86a4SJeremy Kemp #undef __CREATE_IMAGE_ERR
11601*6fee86a4SJeremy Kemp #undef __CREATE_GL_TEXTURE_ERR
11602*6fee86a4SJeremy Kemp #undef __IMAGE_DIMENSION_ERR
11603*6fee86a4SJeremy Kemp #undef __SET_MEM_OBJECT_DESTRUCTOR_CALLBACK_ERR
11604*6fee86a4SJeremy Kemp #undef __CREATE_USER_EVENT_ERR
11605*6fee86a4SJeremy Kemp #undef __SET_USER_EVENT_STATUS_ERR
11606*6fee86a4SJeremy Kemp #undef __SET_EVENT_CALLBACK_ERR
11607*6fee86a4SJeremy Kemp #undef __WAIT_FOR_EVENTS_ERR
11608*6fee86a4SJeremy Kemp #undef __CREATE_KERNEL_ERR
11609*6fee86a4SJeremy Kemp #undef __SET_KERNEL_ARGS_ERR
11610*6fee86a4SJeremy Kemp #undef __CREATE_PROGRAM_WITH_SOURCE_ERR
11611*6fee86a4SJeremy Kemp #undef __CREATE_PROGRAM_WITH_BINARY_ERR
11612*6fee86a4SJeremy Kemp #undef __CREATE_PROGRAM_WITH_IL_ERR
11613*6fee86a4SJeremy Kemp #undef __CREATE_PROGRAM_WITH_BUILT_IN_KERNELS_ERR
11614*6fee86a4SJeremy Kemp #undef __BUILD_PROGRAM_ERR
11615*6fee86a4SJeremy Kemp #undef __COMPILE_PROGRAM_ERR
11616*6fee86a4SJeremy Kemp #undef __LINK_PROGRAM_ERR
11617*6fee86a4SJeremy Kemp #undef __CREATE_KERNELS_IN_PROGRAM_ERR
11618*6fee86a4SJeremy Kemp #undef __CREATE_COMMAND_QUEUE_WITH_PROPERTIES_ERR
11619*6fee86a4SJeremy Kemp #undef __CREATE_SAMPLER_WITH_PROPERTIES_ERR
11620*6fee86a4SJeremy Kemp #undef __SET_COMMAND_QUEUE_PROPERTY_ERR
11621*6fee86a4SJeremy Kemp #undef __ENQUEUE_READ_BUFFER_ERR
11622*6fee86a4SJeremy Kemp #undef __ENQUEUE_READ_BUFFER_RECT_ERR
11623*6fee86a4SJeremy Kemp #undef __ENQUEUE_WRITE_BUFFER_ERR
11624*6fee86a4SJeremy Kemp #undef __ENQUEUE_WRITE_BUFFER_RECT_ERR
11625*6fee86a4SJeremy Kemp #undef __ENQEUE_COPY_BUFFER_ERR
11626*6fee86a4SJeremy Kemp #undef __ENQEUE_COPY_BUFFER_RECT_ERR
11627*6fee86a4SJeremy Kemp #undef __ENQUEUE_FILL_BUFFER_ERR
11628*6fee86a4SJeremy Kemp #undef __ENQUEUE_READ_IMAGE_ERR
11629*6fee86a4SJeremy Kemp #undef __ENQUEUE_WRITE_IMAGE_ERR
11630*6fee86a4SJeremy Kemp #undef __ENQUEUE_COPY_IMAGE_ERR
11631*6fee86a4SJeremy Kemp #undef __ENQUEUE_FILL_IMAGE_ERR
11632*6fee86a4SJeremy Kemp #undef __ENQUEUE_COPY_IMAGE_TO_BUFFER_ERR
11633*6fee86a4SJeremy Kemp #undef __ENQUEUE_COPY_BUFFER_TO_IMAGE_ERR
11634*6fee86a4SJeremy Kemp #undef __ENQUEUE_MAP_BUFFER_ERR
11635*6fee86a4SJeremy Kemp #undef __ENQUEUE_MAP_IMAGE_ERR
11636*6fee86a4SJeremy Kemp #undef __ENQUEUE_MAP_SVM_ERR
11637*6fee86a4SJeremy Kemp #undef __ENQUEUE_FILL_SVM_ERR
11638*6fee86a4SJeremy Kemp #undef __ENQUEUE_COPY_SVM_ERR
11639*6fee86a4SJeremy Kemp #undef __ENQUEUE_UNMAP_SVM_ERR
11640*6fee86a4SJeremy Kemp #undef __ENQUEUE_MAP_IMAGE_ERR
11641*6fee86a4SJeremy Kemp #undef __ENQUEUE_UNMAP_MEM_OBJECT_ERR
11642*6fee86a4SJeremy Kemp #undef __ENQUEUE_NDRANGE_KERNEL_ERR
11643*6fee86a4SJeremy Kemp #undef __ENQUEUE_NATIVE_KERNEL
11644*6fee86a4SJeremy Kemp #undef __ENQUEUE_MIGRATE_MEM_OBJECTS_ERR
11645*6fee86a4SJeremy Kemp #undef __ENQUEUE_MIGRATE_SVM_ERR
11646*6fee86a4SJeremy Kemp #undef __ENQUEUE_ACQUIRE_GL_ERR
11647*6fee86a4SJeremy Kemp #undef __ENQUEUE_RELEASE_GL_ERR
11648*6fee86a4SJeremy Kemp #undef __CREATE_PIPE_ERR
11649*6fee86a4SJeremy Kemp #undef __GET_PIPE_INFO_ERR
11650*6fee86a4SJeremy Kemp #undef __RETAIN_ERR
11651*6fee86a4SJeremy Kemp #undef __RELEASE_ERR
11652*6fee86a4SJeremy Kemp #undef __FLUSH_ERR
11653*6fee86a4SJeremy Kemp #undef __FINISH_ERR
11654*6fee86a4SJeremy Kemp #undef __VECTOR_CAPACITY_ERR
11655*6fee86a4SJeremy Kemp #undef __CREATE_SUB_DEVICES_ERR
11656*6fee86a4SJeremy Kemp #undef __ENQUEUE_ACQUIRE_EXTERNAL_MEMORY_ERR
11657*6fee86a4SJeremy Kemp #undef __ENQUEUE_RELEASE_EXTERNAL_MEMORY_ERR
11658*6fee86a4SJeremy Kemp #undef __ENQUEUE_MARKER_ERR
11659*6fee86a4SJeremy Kemp #undef __ENQUEUE_WAIT_FOR_EVENTS_ERR
11660*6fee86a4SJeremy Kemp #undef __ENQUEUE_BARRIER_ERR
11661*6fee86a4SJeremy Kemp #undef __UNLOAD_COMPILER_ERR
11662*6fee86a4SJeremy Kemp #undef __CREATE_GL_TEXTURE_2D_ERR
11663*6fee86a4SJeremy Kemp #undef __CREATE_GL_TEXTURE_3D_ERR
11664*6fee86a4SJeremy Kemp #undef __CREATE_IMAGE2D_ERR
11665*6fee86a4SJeremy Kemp #undef __CREATE_IMAGE3D_ERR
11666*6fee86a4SJeremy Kemp #undef __CREATE_COMMAND_QUEUE_ERR
11667*6fee86a4SJeremy Kemp #undef __ENQUEUE_TASK_ERR
11668*6fee86a4SJeremy Kemp #undef __CREATE_SAMPLER_ERR
11669*6fee86a4SJeremy Kemp #undef __ENQUEUE_MARKER_WAIT_LIST_ERR
11670*6fee86a4SJeremy Kemp #undef __ENQUEUE_BARRIER_WAIT_LIST_ERR
11671*6fee86a4SJeremy Kemp #undef __CLONE_KERNEL_ERR
11672*6fee86a4SJeremy Kemp #undef __GET_HOST_TIMER_ERR
11673*6fee86a4SJeremy Kemp #undef __GET_DEVICE_AND_HOST_TIMER_ERR
11674*6fee86a4SJeremy Kemp #undef __GET_SEMAPHORE_KHR_INFO_ERR
11675*6fee86a4SJeremy Kemp #undef __CREATE_SEMAPHORE_KHR_WITH_PROPERTIES_ERR
11676*6fee86a4SJeremy Kemp #undef __GET_IMAGE_REQUIREMENT_INFO_EXT_ERR
11677*6fee86a4SJeremy Kemp #undef __ENQUEUE_WAIT_SEMAPHORE_KHR_ERR
11678*6fee86a4SJeremy Kemp #undef __ENQUEUE_SIGNAL_SEMAPHORE_KHR_ERR
11679*6fee86a4SJeremy Kemp #undef __RETAIN_SEMAPHORE_KHR_ERR
11680*6fee86a4SJeremy Kemp #undef __RELEASE_SEMAPHORE_KHR_ERR
11681*6fee86a4SJeremy Kemp #undef __GET_SEMAPHORE_HANDLE_FOR_TYPE_KHR_ERR
11682*6fee86a4SJeremy Kemp 
11683*6fee86a4SJeremy Kemp #endif //CL_HPP_USER_OVERRIDE_ERROR_STRINGS
11684*6fee86a4SJeremy Kemp 
11685*6fee86a4SJeremy Kemp // Extensions
11686*6fee86a4SJeremy Kemp #undef CL_HPP_CREATE_CL_EXT_FCN_PTR_ALIAS_
11687*6fee86a4SJeremy Kemp #undef CL_HPP_INIT_CL_EXT_FCN_PTR_
11688*6fee86a4SJeremy Kemp #undef CL_HPP_INIT_CL_EXT_FCN_PTR_PLATFORM_
11689*6fee86a4SJeremy Kemp 
11690*6fee86a4SJeremy Kemp #undef CL_HPP_DEFINE_STATIC_MEMBER_
11691*6fee86a4SJeremy Kemp 
11692*6fee86a4SJeremy Kemp } // namespace cl
11693*6fee86a4SJeremy Kemp 
11694*6fee86a4SJeremy Kemp #endif // CL_HPP_
11695