1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
// Copyright (c) 2022-2023 Via Technology Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! FFI bindings for [cl_gl.h](https://github.com/KhronosGroup/OpenCL-Headers/blob/main/CL/cl_gl.h)  
//! `OpenCL` extensions are documented in the [OpenCL-Registry](https://github.com/KhronosGroup/OpenCL-Registry)

#![allow(non_camel_case_types, non_upper_case_globals)]

use super::cl::{
    cl_command_queue, cl_context, cl_context_properties, cl_event, cl_mem, cl_mem_flags,
    cl_mem_object_type,
};
use libc::{c_void, size_t};

use super::cl_platform::{cl_GLenum, cl_GLint, cl_GLuint, cl_int, cl_uint};

pub type cl_gl_object_type = cl_uint;
pub type cl_gl_texture_info = cl_uint;
pub type cl_gl_platform_info = cl_uint;
pub type cl_GLsync = *mut c_void;

// cl_gl_object_type = 0x2000 - 0x200F enum values are currently taken
pub const CL_GL_OBJECT_BUFFER: cl_gl_object_type = 0x2000;
pub const CL_GL_OBJECT_TEXTURE2D: cl_gl_object_type = 0x2001;
pub const CL_GL_OBJECT_TEXTURE3D: cl_gl_object_type = 0x2002;
pub const CL_GL_OBJECT_RENDERBUFFER: cl_gl_object_type = 0x2003;
// #ifdef CL_VERSION_1_2
pub const CL_GL_OBJECT_TEXTURE2D_ARRAY: cl_gl_object_type = 0x200E;
pub const CL_GL_OBJECT_TEXTURE1D: cl_gl_object_type = 0x200F;
pub const CL_GL_OBJECT_TEXTURE1D_ARRAY: cl_gl_object_type = 0x2010;
pub const CL_GL_OBJECT_TEXTURE_BUFFER: cl_gl_object_type = 0x2011;
// #endif

// cl_gl_texture_info
pub const CL_GL_TEXTURE_TARGET: cl_gl_texture_info = 0x2004;
pub const CL_GL_MIPMAP_LEVEL: cl_gl_texture_info = 0x2005;
// #ifdef CL_VERSION_1_2
pub const CL_GL_NUM_SAMPLES: cl_gl_texture_info = 0x2012;
// #endif

pub type clGetGLContextInfoKHR_t = Option<
    unsafe extern "C" fn(
        properties: *const cl_context_properties,
        param_name: cl_gl_context_info,
        param_value_size: size_t,
        param_value: *mut c_void,
        param_value_size_ret: *mut size_t,
    ) -> cl_int,
>;
pub type clGetGLContextInfoKHR_fn = clGetGLContextInfoKHR_t;

pub type clCreateFromGLBuffer_t = Option<
    unsafe extern "C" fn(
        context: cl_context,
        flags: cl_mem_flags,
        bufobj: cl_GLuint,
        errcode_ret: *mut cl_int,
    ) -> cl_mem,
>;
pub type clCreateFromGLBuffer_fn = clCreateFromGLBuffer_t;

pub type clCreateFromGLTexture_t = Option<
    unsafe extern "C" fn(
        context: cl_context,
        flags: cl_mem_flags,
        target: cl_GLenum,
        miplevel: cl_GLint,
        texture: cl_GLuint,
        errcode_ret: *mut cl_int,
    ) -> cl_mem,
>;
pub type clCreateFromGLTexture_fn = clCreateFromGLTexture_t;

pub type clCreateFromGLRenderbuffer_t = Option<
    unsafe extern "C" fn(
        context: cl_context,
        flags: cl_mem_flags,
        renderbuffer: cl_GLuint,
        errcode_ret: *mut cl_int,
    ) -> cl_mem,
>;
pub type clCreateFromGLRenderbuffer_fn = clCreateFromGLRenderbuffer_t;

pub type clGetGLObjectInfo_t = Option<
    unsafe extern "C" fn(
        memobj: cl_mem,
        gl_object_type: *mut cl_gl_object_type,
        gl_object_name: *mut cl_GLuint,
    ) -> cl_int,
>;
pub type clGetGLObjectInfo_fn = clGetGLObjectInfo_t;

pub type clGetGLTextureInfo_t = Option<
    unsafe extern "C" fn(
        memobj: cl_mem,
        param_name: cl_gl_texture_info,
        param_value_size: size_t,
        param_value: *mut c_void,
        param_value_size_ret: *mut size_t,
    ) -> cl_int,
>;
pub type clGetGLTextureInfo_fn = clGetGLTextureInfo_t;

pub type clEnqueueAcquireGLObjects_t = Option<
    unsafe extern "C" fn(
        command_queue: cl_command_queue,
        num_objects: cl_uint,
        mem_objects: *const cl_mem,
        num_events_in_wait_list: cl_uint,
        event_wait_list: *const cl_event,
        event: *mut cl_event,
    ) -> cl_int,
>;
pub type clEnqueueAcquireGLObjects_fn = clEnqueueAcquireGLObjects_t;

pub type clEnqueueReleaseGLObjects_t = Option<
    unsafe extern "C" fn(
        command_queue: cl_command_queue,
        num_objects: cl_uint,
        mem_objects: *const cl_mem,
        num_events_in_wait_list: cl_uint,
        event_wait_list: *const cl_event,
        event: *mut cl_event,
    ) -> cl_int,
>;
pub type clEnqueueReleaseGLObjects_fn = clEnqueueReleaseGLObjects_t;

pub type clCreateFromGLTexture2D_t = Option<
    unsafe extern "C" fn(
        context: cl_context,
        flags: cl_mem_flags,
        target: cl_GLenum,
        miplevel: cl_GLint,
        texture: cl_GLuint,
        errcode_ret: *mut cl_int,
    ) -> cl_mem,
>;
pub type clCreateFromGLTexture2D_fn = clCreateFromGLTexture2D_t;

pub type clCreateFromGLTexture3D_t = Option<
    unsafe extern "C" fn(
        context: cl_context,
        flags: cl_mem_flags,
        target: cl_GLenum,
        miplevel: cl_GLint,
        texture: cl_GLuint,
        errcode_ret: *mut cl_int,
    ) -> cl_mem,
>;
pub type clCreateFromGLTexture3D_fn = clCreateFromGLTexture3D_t;

pub type clCreateEventFromGLsyncKHR_t = Option<
    unsafe extern "C" fn(
        context: cl_context,
        sync: cl_GLsync,
        errcode_ret: *mut cl_int,
    ) -> cl_event,
>;
pub type clCreateEventFromGLsyncKHR_fn = clCreateEventFromGLsyncKHR_t;

pub type clGetSupportedGLTextureFormatsINTEL_t = Option<
    unsafe extern "C" fn(
        context: cl_context,
        flags: cl_mem_flags,
        image_type: cl_mem_object_type,
        num_entries: cl_uint,
        gl_formats: *mut cl_GLenum,
        num_texture_formats: *mut cl_uint,
    ) -> cl_int,
>;
pub type clGetSupportedGLTextureFormatsINTEL_fn = clGetSupportedGLTextureFormatsINTEL_t;

#[cfg_attr(not(target_os = "macos"), link(name = "OpenCL"))]
#[cfg_attr(target_os = "macos", link(name = "OpenCL", kind = "framework"))]
extern "system" {

    pub fn clCreateFromGLBuffer(
        context: cl_context,
        flags: cl_mem_flags,
        bufobj: cl_GLuint,
        errcode_ret: *mut cl_int,
    ) -> cl_mem;

    #[cfg(feature = "CL_VERSION_1_2")]
    pub fn clCreateFromGLTexture(
        context: cl_context,
        flags: cl_mem_flags,
        target: cl_GLenum,
        miplevel: cl_GLint,
        texture: cl_GLuint,
        errcode_ret: *mut cl_int,
    ) -> cl_mem;

    pub fn clCreateFromGLRenderbuffer(
        context: cl_context,
        flags: cl_mem_flags,
        renderbuffer: cl_GLuint,
        errcode_ret: *mut cl_int,
    ) -> cl_mem;

    pub fn clGetGLObjectInfo(
        memobj: cl_mem,
        gl_object_type: *mut cl_gl_object_type,
        gl_object_name: *mut cl_GLuint,
    ) -> cl_int;

    pub fn clGetGLTextureInfo(
        memobj: cl_mem,
        param_name: cl_gl_texture_info,
        param_value_size: size_t,
        param_value: *mut c_void,
        param_value_size_ret: *mut size_t,
    ) -> cl_int;

    pub fn clEnqueueAcquireGLObjects(
        command_queue: cl_command_queue,
        num_objects: cl_uint,
        mem_objects: *const cl_mem,
        num_events_in_wait_list: cl_uint,
        event_wait_list: *const cl_event,
        event: *mut cl_event,
    ) -> cl_int;

    pub fn clEnqueueReleaseGLObjects(
        command_queue: cl_command_queue,
        num_objects: cl_uint,
        mem_objects: *const cl_mem,
        num_events_in_wait_list: cl_uint,
        event_wait_list: *const cl_event,
        event: *mut cl_event,
    ) -> cl_int;

    // Deprecated OpenCL 1.1 APIs
    #[cfg_attr(
        any(
            feature = "CL_VERSION_1_2",
            feature = "CL_VERSION_2_0",
            feature = "CL_VERSION_2_1",
            feature = "CL_VERSION_2_2",
            feature = "CL_VERSION_3_0"
        ),
        deprecated(
            since = "0.1.0",
            note = "From CL_VERSION_1_2 use clCreateFromGLTexture"
        )
    )]
    pub fn clCreateFromGLTexture2D(
        context: cl_context,
        flags: cl_mem_flags,
        texture_target: cl_GLenum,
        miplevel: cl_GLint,
        texture: cl_GLuint,
        errcode_ret: *mut cl_int,
    ) -> cl_mem;

    #[cfg_attr(
        any(
            feature = "CL_VERSION_1_2",
            feature = "CL_VERSION_2_0",
            feature = "CL_VERSION_2_1",
            feature = "CL_VERSION_2_2",
            feature = "CL_VERSION_3_0"
        ),
        deprecated(
            since = "0.1.0",
            note = "From CL_VERSION_1_2 use clCreateFromGLTexture"
        )
    )]
    pub fn clCreateFromGLTexture3D(
        context: cl_context,
        flags: cl_mem_flags,
        texture_target: cl_GLenum,
        miplevel: cl_GLint,
        texture: cl_GLuint,
        errcode_ret: *mut cl_int,
    ) -> cl_mem;

}

// cl_khr_gl_sharing extension
// * NOTE: Originally lower case: `cl_kgr_gl_sharing`
pub const CL_KHR_GL_SHARING: cl_int = 1;

pub type cl_gl_context_info = cl_uint;

// Additional Error Codes
pub const CL_INVALID_GL_SHAREGROUP_REFERENCE_KHR: cl_int = -1000;

// cl_gl_context_info
pub const CL_CURRENT_DEVICE_FOR_GL_CONTEXT_KHR: cl_gl_context_info = 0x2006;
pub const CL_DEVICES_FOR_GL_CONTEXT_KHR: cl_gl_context_info = 0x2007;

// Additional cl_context_properties
pub const CL_GL_CONTEXT_KHR: cl_context_properties = 0x2008;
pub const CL_EGL_DISPLAY_KHR: cl_context_properties = 0x2009;
pub const CL_GLX_DISPLAY_KHR: cl_context_properties = 0x200A;
pub const CL_WGL_HDC_KHR: cl_context_properties = 0x200B;
pub const CL_CGL_SHAREGROUP_KHR: cl_context_properties = 0x200C;

// cl_khr_gl_event extension
pub const CL_COMMAND_GL_FENCE_SYNC_OBJECT_KHR: cl_uint = 0x200D;

#[cfg_attr(not(target_os = "macos"), link(name = "OpenCL"))]
#[cfg_attr(target_os = "macos", link(name = "OpenCL", kind = "framework"))]
extern "system" {

    pub fn clGetGLContextInfoKHR(
        properties: *const cl_context_properties,
        param_name: cl_gl_context_info,
        param_value_size: size_t,
        param_value: *mut c_void,
        param_value_size_ret: *mut size_t,
    ) -> cl_int;

    pub fn clCreateEventFromGLsyncKHR(
        context: cl_context,
        sync: cl_GLsync,
        errcode_ret: *mut cl_int,
    ) -> cl_event;

    pub fn clGetSupportedGLTextureFormatsINTEL(
        context: cl_context,
        flags: cl_mem_flags,
        image_type: cl_mem_object_type,
        num_entries: cl_uint,
        gl_formats: *mut cl_GLenum,
        num_texture_formats: *mut cl_uint,
    ) -> cl_int;
}