1 /**************************************************************************
2  *
3  * Copyright (C) 2014 Red Hat Inc.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included
13  * in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
19  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21  * OTHER DEALINGS IN THE SOFTWARE.
22  *
23  **************************************************************************/
24 
25 /* library interface from QEMU to virglrenderer */
26 
27 #ifndef VIRGLRENDERER_H
28 #define VIRGLRENDERER_H
29 
30 #include <stdint.h>
31 #include <stdbool.h>
32 #include <stdarg.h>
33 
34 struct virgl_box;
35 struct iovec;
36 
37 #define VIRGL_EXPORT  __attribute__((visibility("default")))
38 
39 typedef void *virgl_renderer_gl_context;
40 
41 struct virgl_renderer_gl_ctx_param {
42    int version;
43    bool shared;
44    int major_ver;
45    int minor_ver;
46 };
47 
48 #ifdef VIRGL_RENDERER_UNSTABLE_APIS
49 #define VIRGL_RENDERER_CALLBACKS_VERSION 3
50 #else
51 #define VIRGL_RENDERER_CALLBACKS_VERSION 2
52 #endif
53 
54 struct virgl_renderer_callbacks {
55    int version;
56    void (*write_fence)(void *cookie, uint32_t fence);
57 
58    /* interact with GL implementation */
59    virgl_renderer_gl_context (*create_gl_context)(void *cookie, int scanout_idx, struct virgl_renderer_gl_ctx_param *param);
60    void (*destroy_gl_context)(void *cookie, virgl_renderer_gl_context ctx);
61    int (*make_current)(void *cookie, int scanout_idx, virgl_renderer_gl_context ctx);
62 
63    int (*get_drm_fd)(void *cookie); /* v2, used with flags & VIRGL_RENDERER_USE_EGL */
64 
65 #ifdef VIRGL_RENDERER_UNSTABLE_APIS
66    void (*write_context_fence)(void *cookie, uint32_t ctx_id, uint64_t queue_id, void *fence_cookie);
67 #endif
68 };
69 
70 /* virtio-gpu compatible interface */
71 #define VIRGL_RENDERER_USE_EGL 1
72 /*
73  * Wait for sync objects in thread rather than polling
74  * need to use virgl_renderer_get_poll_fd to know if this feature is in effect.
75  */
76 #define VIRGL_RENDERER_THREAD_SYNC 2
77 #define VIRGL_RENDERER_USE_GLX (1 << 2)
78 #define VIRGL_RENDERER_USE_SURFACELESS (1 << 3)
79 #define VIRGL_RENDERER_USE_GLES (1 << 4)
80 
81 #ifdef VIRGL_RENDERER_UNSTABLE_APIS
82 /*
83  * Blob resources used with the 3D driver must be able to be represented as file descriptors.
84  * The typical use case is the virtual machine manager (or vtest) is running in a multiprocess
85  * mode. In a standard Linux setup, that means the KVM process is different from the process that
86  * instantiated virglrenderer. For zero-copy capability to work, file descriptors must be used.
87  *
88  * VMMs that advertise support for the virtio-gpu feature VIRTIO_GPU_F_RESOURCE_BLOB and run in
89  * a multi-process mode *must* specify this flag.
90  */
91 #define VIRGL_RENDERER_USE_EXTERNAL_BLOB (1 << 5)
92 
93 #endif /* VIRGL_RENDERER_UNSTABLE_APIS */
94 
95 VIRGL_EXPORT int virgl_renderer_init(void *cookie, int flags, struct virgl_renderer_callbacks *cb);
96 VIRGL_EXPORT void virgl_renderer_poll(void); /* force fences */
97 
98 /* we need to give qemu the cursor resource contents */
99 VIRGL_EXPORT void *virgl_renderer_get_cursor_data(uint32_t resource_id, uint32_t *width, uint32_t *height);
100 
101 VIRGL_EXPORT void virgl_renderer_get_rect(int resource_id, struct iovec *iov, unsigned int num_iovs,
102                                           uint32_t offset, int x, int y, int width, int height);
103 
104 VIRGL_EXPORT int virgl_renderer_get_fd_for_texture(uint32_t tex_id, int *fd);
105 VIRGL_EXPORT int virgl_renderer_get_fd_for_texture2(uint32_t tex_id, int *fd, int *stride, int *offset);
106 
107 /*
108  * These are only here for compatibility-reasons. In the future, use the flags
109  * from virgl_hw.h instead.
110  */
111 #define VIRGL_RES_BIND_DEPTH_STENCIL (1 << 0)
112 #define VIRGL_RES_BIND_RENDER_TARGET (1 << 1)
113 #define VIRGL_RES_BIND_SAMPLER_VIEW  (1 << 3)
114 #define VIRGL_RES_BIND_VERTEX_BUFFER (1 << 4)
115 #define VIRGL_RES_BIND_INDEX_BUFFER  (1 << 5)
116 #define VIRGL_RES_BIND_CONSTANT_BUFFER (1 << 6)
117 #define VIRGL_RES_BIND_STREAM_OUTPUT (1 << 11)
118 #define VIRGL_RES_BIND_CURSOR        (1 << 16)
119 #define VIRGL_RES_BIND_CUSTOM        (1 << 17)
120 #define VIRGL_RES_BIND_SCANOUT       (1 << 18)
121 #define VIRGL_RES_BIND_SHARED        (1 << 20)
122 
123 enum virgl_renderer_structure_type_v0 {
124    VIRGL_RENDERER_STRUCTURE_TYPE_NONE = 0,
125    VIRGL_RENDERER_STRUCTURE_TYPE_EXPORT_QUERY = (1 << 0),
126    VIRGL_RENDERER_STRUCTURE_TYPE_SUPPORTED_STRUCTURES = (1 << 1),
127 };
128 
129 struct virgl_renderer_resource_create_args {
130    uint32_t handle;
131    uint32_t target;
132    uint32_t format;
133    uint32_t bind;
134    uint32_t width;
135    uint32_t height;
136    uint32_t depth;
137    uint32_t array_size;
138    uint32_t last_level;
139    uint32_t nr_samples;
140    uint32_t flags;
141 };
142 
143 struct virgl_renderer_hdr {
144    uint32_t stype;
145    uint32_t stype_version;
146    uint32_t size;
147 };
148 
149 /*
150  * "out_num_fds" represents the number of distinct kernel buffers backing an
151  * allocation. If this number or 'out_fourcc' is zero, the resource is not
152  * exportable. The "out_fds" field will be populated with "out_num_fds" file
153  * descriptors if "in_export_fds" is non-zero.
154  */
155 struct virgl_renderer_export_query {
156    struct virgl_renderer_hdr hdr;
157    uint32_t in_resource_id;
158 
159    uint32_t out_num_fds;
160    uint32_t in_export_fds;
161    uint32_t out_fourcc;
162    uint32_t pad;
163 
164    int32_t out_fds[4];
165    uint32_t out_strides[4];
166    uint32_t out_offsets[4];
167    uint64_t out_modifier;
168 };
169 
170 /*
171  * "out_supported_structures_mask" is a bitmask representing the structures that
172  * virglrenderer knows how to handle for a given "in_stype_version".
173  */
174 
175 struct virgl_renderer_supported_structures {
176    struct virgl_renderer_hdr hdr;
177    uint32_t in_stype_version;
178    uint32_t out_supported_structures_mask;
179 };
180 
181 /* new API */
182 /* This typedef must be kept in sync with vrend_debug.h */
183 typedef void (*virgl_debug_callback_type)(const char *fmt, va_list ap);
184 
185 VIRGL_EXPORT int virgl_renderer_resource_create(struct virgl_renderer_resource_create_args *args, struct iovec *iov, uint32_t num_iovs);
186 VIRGL_EXPORT int virgl_renderer_resource_import_eglimage(struct virgl_renderer_resource_create_args *args, void *image);
187 VIRGL_EXPORT void virgl_renderer_resource_unref(uint32_t res_handle);
188 
189 VIRGL_EXPORT void virgl_renderer_resource_set_priv(uint32_t res_handle, void *priv);
190 VIRGL_EXPORT void *virgl_renderer_resource_get_priv(uint32_t res_handle);
191 
192 VIRGL_EXPORT int virgl_renderer_context_create(uint32_t handle, uint32_t nlen, const char *name);
193 VIRGL_EXPORT void virgl_renderer_context_destroy(uint32_t handle);
194 
195 VIRGL_EXPORT int virgl_renderer_submit_cmd(void *buffer,
196                                            int ctx_id,
197                                            int ndw);
198 
199 VIRGL_EXPORT int virgl_renderer_transfer_read_iov(uint32_t handle, uint32_t ctx_id,
200                                                   uint32_t level, uint32_t stride,
201                                                   uint32_t layer_stride,
202                                                   struct virgl_box *box,
203                                                   uint64_t offset, struct iovec *iov,
204                                                   int iovec_cnt);
205 
206 VIRGL_EXPORT int virgl_renderer_transfer_write_iov(uint32_t handle,
207                                                    uint32_t ctx_id,
208                                                    int level,
209                                                    uint32_t stride,
210                                                    uint32_t layer_stride,
211                                                    struct virgl_box *box,
212                                                    uint64_t offset,
213                                                    struct iovec *iovec,
214                                                    unsigned int iovec_cnt);
215 
216 VIRGL_EXPORT void virgl_renderer_get_cap_set(uint32_t set, uint32_t *max_ver,
217                                              uint32_t *max_size);
218 
219 VIRGL_EXPORT void virgl_renderer_fill_caps(uint32_t set, uint32_t version,
220                                            void *caps);
221 
222 VIRGL_EXPORT int virgl_renderer_resource_attach_iov(int res_handle, struct iovec *iov,
223                                                     int num_iovs);
224 VIRGL_EXPORT void virgl_renderer_resource_detach_iov(int res_handle, struct iovec **iov, int *num_iovs);
225 
226 VIRGL_EXPORT int virgl_renderer_create_fence(int client_fence_id, uint32_t ctx_id);
227 
228 VIRGL_EXPORT void virgl_renderer_force_ctx_0(void);
229 
230 VIRGL_EXPORT void virgl_renderer_ctx_attach_resource(int ctx_id, int res_handle);
231 VIRGL_EXPORT void virgl_renderer_ctx_detach_resource(int ctx_id, int res_handle);
232 
233 VIRGL_EXPORT virgl_debug_callback_type virgl_set_debug_callback(virgl_debug_callback_type cb);
234 
235 /* return information about a resource */
236 
237 struct virgl_renderer_resource_info {
238    uint32_t handle;
239    uint32_t virgl_format;
240    uint32_t width;
241    uint32_t height;
242    uint32_t depth;
243    uint32_t flags;
244    uint32_t tex_id;
245    uint32_t stride;
246    int drm_fourcc;
247 };
248 
249 VIRGL_EXPORT int virgl_renderer_resource_get_info(int res_handle,
250                                                   struct virgl_renderer_resource_info *info);
251 
252 VIRGL_EXPORT void virgl_renderer_cleanup(void *cookie);
253 
254 /* reset the rendererer - destroy all contexts and resource */
255 VIRGL_EXPORT void virgl_renderer_reset(void);
256 
257 VIRGL_EXPORT int virgl_renderer_get_poll_fd(void);
258 
259 VIRGL_EXPORT int virgl_renderer_execute(void *execute_args, uint32_t execute_size);
260 
261 /*
262  * These are unstable APIs for development only. Use these for development/testing purposes
263  * only, not in production
264  */
265 #ifdef VIRGL_RENDERER_UNSTABLE_APIS
266 
267 #define VIRGL_RENDERER_CONTEXT_FLAG_CAPSET_ID_MASK 0xff
268 
269 VIRGL_EXPORT int virgl_renderer_context_create_with_flags(uint32_t ctx_id,
270                                                           uint32_t ctx_flags,
271                                                           uint32_t nlen,
272                                                           const char *name);
273 
274 #define VIRGL_RENDERER_BLOB_MEM_GUEST             0x0001
275 #define VIRGL_RENDERER_BLOB_MEM_HOST3D            0x0002
276 #define VIRGL_RENDERER_BLOB_MEM_HOST3D_GUEST      0x0003
277 
278 #define VIRGL_RENDERER_BLOB_FLAG_USE_MAPPABLE     0x0001
279 #define VIRGL_RENDERER_BLOB_FLAG_USE_SHAREABLE    0x0002
280 #define VIRGL_RENDERER_BLOB_FLAG_USE_CROSS_DEVICE 0x0004
281 
282 struct virgl_renderer_resource_create_blob_args
283 {
284    uint32_t res_handle;
285    uint32_t ctx_id;
286    uint32_t blob_mem;
287    uint32_t blob_flags;
288    uint64_t blob_id;
289    uint64_t size;
290    const struct iovec *iovecs;
291    uint32_t num_iovs;
292 };
293 
294 VIRGL_EXPORT int
295 virgl_renderer_resource_create_blob(const struct virgl_renderer_resource_create_blob_args *args);
296 
297 VIRGL_EXPORT int virgl_renderer_resource_map(uint32_t res_handle, void **map, uint64_t *out_size);
298 
299 VIRGL_EXPORT int virgl_renderer_resource_unmap(uint32_t res_handle);
300 
301 #define VIRGL_RENDERER_MAP_CACHE_MASK      0x0f
302 #define VIRGL_RENDERER_MAP_CACHE_NONE      0x00
303 #define VIRGL_RENDERER_MAP_CACHE_CACHED    0x01
304 #define VIRGL_RENDERER_MAP_CACHE_UNCACHED  0x02
305 #define VIRGL_RENDERER_MAP_CACHE_WC        0x03
306 
307 VIRGL_EXPORT int virgl_renderer_resource_get_map_info(uint32_t res_handle, uint32_t *map_info);
308 
309 #define VIRGL_RENDERER_BLOB_FD_TYPE_DMABUF        0x0001
310 #define VIRGL_RENDERER_BLOB_FD_TYPE_OPAQUE        0x0002
311 
312 VIRGL_EXPORT int
313 virgl_renderer_resource_export_blob(uint32_t res_id, uint32_t *fd_type, int *fd);
314 
315 VIRGL_EXPORT int
316 virgl_renderer_export_fence(uint32_t client_fence_id, int *fd);
317 
318 #define VIRGL_RENDERER_FENCE_FLAG_MERGEABLE      (1 << 0)
319 VIRGL_EXPORT int virgl_renderer_context_create_fence(uint32_t ctx_id,
320                                                      uint32_t flags,
321                                                      uint64_t queue_id,
322                                                      void *fence_cookie);
323 VIRGL_EXPORT void virgl_renderer_context_poll(uint32_t ctx_id); /* force fences */
324 VIRGL_EXPORT int virgl_renderer_context_get_poll_fd(uint32_t ctx_id);
325 
326 #endif /* VIRGL_RENDERER_UNSTABLE_APIS */
327 
328 #endif
329