1 /*
2  * Mesa 3-D graphics library
3  *
4  * Copyright 2016 Advanced Micro Devices, Inc.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the "Software"),
8  * to deal in the Software without restriction, including without limitation
9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  * and/or sell copies of the Software, and to permit persons to whom the
11  * Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included
14  * in all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22  * OTHER DEALINGS IN THE SOFTWARE.
23  */
24 
25 /* Mesa OpenGL inter-driver interoperability interface designed for but not
26  * limited to OpenCL.
27  *
28  * This is a driver-agnostic, backward-compatible interface. The structures
29  * are only allowed to grow. They can never shrink and their members can
30  * never be removed, renamed, or redefined.
31  *
32  * The interface doesn't return a lot of static texture parameters like
33  * width, height, etc. It mainly returns mutable buffer and texture view
34  * parameters that can't be part of the texture allocation (because they are
35  * mutable). If drivers want to return more data or want to return static
36  * allocation parameters, they can do it in one of these two ways:
37  * - attaching the data to the DMABUF handle in a driver-specific way
38  * - passing the data via "out_driver_data" in the "in" structure.
39  *
40  * Mesa is expected to do a lot of error checking on behalf of OpenCL, such
41  * as checking the target, miplevel, and texture completeness.
42  *
43  * OpenCL, on the other hand, needs to check if the display+context combo
44  * is compatible with the OpenCL driver by querying the device information.
45  * It also needs to check if the texture internal format and channel ordering
46  * (returned in a driver-specific way) is supported by OpenCL, among other
47  * things.
48  */
49 
50 #ifndef MESA_GLINTEROP_H
51 #define MESA_GLINTEROP_H
52 
53 #include <stddef.h>
54 #include <stdint.h>
55 
56 #ifdef __cplusplus
57 extern "C" {
58 #endif
59 
60 /* Forward declarations to avoid inclusion of GL/glx.h */
61 #ifndef GLX_H
62 struct _XDisplay;
63 struct __GLXcontextRec;
64 #endif
65 
66 /* Forward declarations to avoid inclusion of EGL/egl.h */
67 #ifndef __egl_h_
68 typedef void *EGLDisplay;
69 typedef void *EGLContext;
70 #endif
71 
72 /** Returned error codes. */
73 enum {
74    MESA_GLINTEROP_SUCCESS = 0,
75    MESA_GLINTEROP_OUT_OF_RESOURCES,
76    MESA_GLINTEROP_OUT_OF_HOST_MEMORY,
77    MESA_GLINTEROP_INVALID_OPERATION,
78    MESA_GLINTEROP_INVALID_VERSION,
79    MESA_GLINTEROP_INVALID_DISPLAY,
80    MESA_GLINTEROP_INVALID_CONTEXT,
81    MESA_GLINTEROP_INVALID_TARGET,
82    MESA_GLINTEROP_INVALID_OBJECT,
83    MESA_GLINTEROP_INVALID_MIP_LEVEL,
84    MESA_GLINTEROP_UNSUPPORTED
85 };
86 
87 /** Access flags. */
88 enum {
89    MESA_GLINTEROP_ACCESS_READ_WRITE = 0,
90    MESA_GLINTEROP_ACCESS_READ_ONLY,
91    MESA_GLINTEROP_ACCESS_WRITE_ONLY
92 };
93 
94 #define MESA_GLINTEROP_DEVICE_INFO_VERSION 1
95 
96 /**
97  * Device information returned by Mesa.
98  */
99 struct mesa_glinterop_device_info {
100    /* The caller should set this to the version of the struct they support */
101    /* The callee will overwrite it if it supports a lower version.
102     *
103     * The caller should check the value and access up-to the version supported
104     * by the callee.
105     */
106    /* NOTE: Do not use the MESA_GLINTEROP_DEVICE_INFO_VERSION macro */
107    uint32_t version;
108 
109    /* PCI location */
110    uint32_t pci_segment_group;
111    uint32_t pci_bus;
112    uint32_t pci_device;
113    uint32_t pci_function;
114 
115    /* Device identification */
116    uint32_t vendor_id;
117    uint32_t device_id;
118 
119    /* Structure version 1 ends here. */
120 };
121 
122 #define MESA_GLINTEROP_EXPORT_IN_VERSION 1
123 
124 /**
125  * Input parameters to Mesa interop export functions.
126  */
127 struct mesa_glinterop_export_in {
128    /* The caller should set this to the version of the struct they support */
129    /* The callee will overwrite it if it supports a lower version.
130     *
131     * The caller should check the value and access up-to the version supported
132     * by the callee.
133     */
134    /* NOTE: Do not use the MESA_GLINTEROP_EXPORT_IN_VERSION macro */
135    uint32_t version;
136 
137    /* One of the following:
138     * - GL_TEXTURE_BUFFER
139     * - GL_TEXTURE_1D
140     * - GL_TEXTURE_2D
141     * - GL_TEXTURE_3D
142     * - GL_TEXTURE_RECTANGLE
143     * - GL_TEXTURE_1D_ARRAY
144     * - GL_TEXTURE_2D_ARRAY
145     * - GL_TEXTURE_CUBE_MAP_ARRAY
146     * - GL_TEXTURE_CUBE_MAP
147     * - GL_TEXTURE_CUBE_MAP_POSITIVE_X
148     * - GL_TEXTURE_CUBE_MAP_NEGATIVE_X
149     * - GL_TEXTURE_CUBE_MAP_POSITIVE_Y
150     * - GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
151     * - GL_TEXTURE_CUBE_MAP_POSITIVE_Z
152     * - GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
153     * - GL_TEXTURE_2D_MULTISAMPLE
154     * - GL_TEXTURE_2D_MULTISAMPLE_ARRAY
155     * - GL_TEXTURE_EXTERNAL_OES
156     * - GL_RENDERBUFFER
157     * - GL_ARRAY_BUFFER
158     */
159    unsigned target;
160 
161    /* If target is GL_ARRAY_BUFFER, it's a buffer object.
162     * If target is GL_RENDERBUFFER, it's a renderbuffer object.
163     * If target is GL_TEXTURE_*, it's a texture object.
164     */
165    unsigned obj;
166 
167    /* Mipmap level. Ignored for non-texture objects. */
168    unsigned miplevel;
169 
170    /* One of MESA_GLINTEROP_ACCESS_* flags. This describes how the exported
171     * object is going to be used.
172     */
173    uint32_t access;
174 
175    /* Size of memory pointed to by out_driver_data. */
176    uint32_t out_driver_data_size;
177 
178    /* If the caller wants to query driver-specific data about the OpenGL
179     * object, this should point to the memory where that data will be stored.
180     * This is expected to be a temporary staging memory. The pointer is not
181     * allowed to be saved for later use by Mesa.
182     */
183    void *out_driver_data;
184    /* Structure version 1 ends here. */
185 };
186 
187 #define MESA_GLINTEROP_EXPORT_OUT_VERSION 1
188 
189 /**
190  * Outputs of Mesa interop export functions.
191  */
192 struct mesa_glinterop_export_out {
193    /* The caller should set this to the version of the struct they support */
194    /* The callee will overwrite it if it supports a lower version.
195     *
196     * The caller should check the value and access up-to the version supported
197     * by the callee.
198     */
199    /* NOTE: Do not use the MESA_GLINTEROP_EXPORT_OUT_VERSION macro */
200    uint32_t version;
201 
202    /* The DMABUF handle. It must be closed by the caller using the POSIX
203     * close() function when it's not needed anymore. Mesa is not responsible
204     * for closing the handle.
205     *
206     * Not closing the handle by the caller will lead to a resource leak,
207     * will prevent releasing the GPU buffer, and may prevent creating new
208     * DMABUF handles within the process.
209     */
210    int dmabuf_fd;
211 
212    /* The mutable OpenGL internal format specified by glTextureView or
213     * glTexBuffer. If the object is not one of those, the original internal
214     * format specified by glTexStorage, glTexImage, or glRenderbufferStorage
215     * will be returned.
216     */
217    unsigned internal_format;
218 
219    /* Buffer offset and size for GL_ARRAY_BUFFER and GL_TEXTURE_BUFFER.
220     * This allows interop with suballocations (a buffer allocated within
221     * a larger buffer).
222     *
223     * Parameters specified by glTexBufferRange for GL_TEXTURE_BUFFER are
224     * applied to these and can shrink the range further.
225     */
226    ptrdiff_t buf_offset;
227    ptrdiff_t buf_size;
228 
229    /* Parameters specified by glTextureView. If the object is not a texture
230     * view, default parameters covering the whole texture will be returned.
231     */
232    unsigned view_minlevel;
233    unsigned view_numlevels;
234    unsigned view_minlayer;
235    unsigned view_numlayers;
236 
237    /* The number of bytes written to out_driver_data. */
238    uint32_t out_driver_data_written;
239    /* Structure version 1 ends here. */
240 };
241 
242 
243 /**
244  * Query device information.
245  *
246  * \param dpy        GLX display
247  * \param context    GLX context
248  * \param out        where to return the information
249  *
250  * \return MESA_GLINTEROP_SUCCESS or MESA_GLINTEROP_* != 0 on error
251  */
252 int
253 MesaGLInteropGLXQueryDeviceInfo(struct _XDisplay *dpy, struct __GLXcontextRec *context,
254                                 struct mesa_glinterop_device_info *out);
255 
256 
257 /**
258  * Same as MesaGLInteropGLXQueryDeviceInfo except that it accepts EGLDisplay
259  * and EGLContext.
260  */
261 int
262 MesaGLInteropEGLQueryDeviceInfo(EGLDisplay dpy, EGLContext context,
263                                 struct mesa_glinterop_device_info *out);
264 
265 
266 /**
267  * Create and return a DMABUF handle corresponding to the given OpenGL
268  * object, and return other parameters about the OpenGL object.
269  *
270  * \param dpy        GLX display
271  * \param context    GLX context
272  * \param in         input parameters
273  * \param out        return values
274  *
275  * \return MESA_GLINTEROP_SUCCESS or MESA_GLINTEROP_* != 0 on error
276  */
277 int
278 MesaGLInteropGLXExportObject(struct _XDisplay *dpy, struct __GLXcontextRec *context,
279                              struct mesa_glinterop_export_in *in,
280                              struct mesa_glinterop_export_out *out);
281 
282 
283 /**
284  * Same as MesaGLInteropGLXExportObject except that it accepts
285  * EGLDisplay and EGLContext.
286  */
287 int
288 MesaGLInteropEGLExportObject(EGLDisplay dpy, EGLContext context,
289                              struct mesa_glinterop_export_in *in,
290                              struct mesa_glinterop_export_out *out);
291 
292 
293 typedef int (PFNMESAGLINTEROPGLXQUERYDEVICEINFOPROC)(struct _XDisplay *dpy, struct __GLXcontextRec *context,
294                                                      struct mesa_glinterop_device_info *out);
295 typedef int (PFNMESAGLINTEROPEGLQUERYDEVICEINFOPROC)(EGLDisplay dpy, EGLContext context,
296                                                      struct mesa_glinterop_device_info *out);
297 typedef int (PFNMESAGLINTEROPGLXEXPORTOBJECTPROC)(struct _XDisplay *dpy, struct __GLXcontextRec *context,
298                                                   struct mesa_glinterop_export_in *in,
299                                                   struct mesa_glinterop_export_out *out);
300 typedef int (PFNMESAGLINTEROPEGLEXPORTOBJECTPROC)(EGLDisplay dpy, EGLContext context,
301                                                   struct mesa_glinterop_export_in *in,
302                                                   struct mesa_glinterop_export_out *out);
303 
304 #ifdef __cplusplus
305 }
306 #endif
307 
308 #endif /* MESA_GLINTEROP_H */
309