1 // Copyright 2023 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef VIRTGPU_GFXSTREAM_RENDERER_H
16 #define VIRTGPU_GFXSTREAM_RENDERER_H
17 
18 /* An implementation of virtio-gpu-3d that streams rendering commands. */
19 
20 #include <stddef.h>
21 #include <stdint.h>
22 
23 #if defined(_WIN32)
24 #if !defined(GFXSTREAM_NO_IOVEC)
25 struct iovec {
26     void* iov_base; /* Starting address */
27     size_t iov_len; /* Length in bytes */
28 };
29 #endif
30 #else
31 #include <sys/uio.h>
32 #endif
33 
34 struct stream_renderer_box {
35     uint32_t x, y, z;
36     uint32_t w, h, d;
37 };
38 
39 #ifdef __cplusplus
40 extern "C" {
41 #endif
42 
43 /**
44  * Versioning
45  */
46 #define STREAM_RENDERER_VERSION_MAJOR 0
47 #define STREAM_RENDERER_VERSION_MINOR 1
48 #define STREAM_RENDERER_VERSION_PATCH 2
49 
50 #ifdef _WIN32
51 #define VG_EXPORT __declspec(dllexport)
52 #else
53 #define VG_EXPORT __attribute__((visibility("default")))
54 #endif
55 
56 struct stream_renderer_resource_create_args {
57     uint32_t handle;
58     uint32_t target;
59     uint32_t format;
60     uint32_t bind;
61     uint32_t width;
62     uint32_t height;
63     uint32_t depth;
64     uint32_t array_size;
65     uint32_t last_level;
66     uint32_t nr_samples;
67     uint32_t flags;
68 };
69 
70 #define STREAM_RENDERER_FLAG_FENCE (1 << 0)
71 #define STREAM_RENDERER_FLAG_FENCE_RING_IDX (1 << 1)
72 #define STREAM_RENDERER_FLAG_FENCE_SHAREABLE (1 << 2)
73 struct stream_renderer_fence {
74     uint32_t flags;
75     uint64_t fence_id;
76     uint32_t ctx_id;
77     uint8_t ring_idx;
78 };
79 
80 #define STREAM_MEM_HANDLE_TYPE_OPAQUE_FD 0x1
81 #define STREAM_MEM_HANDLE_TYPE_DMABUF 0x2
82 #define STREAM_MEM_HANDLE_TYPE_OPAQUE_WIN32 0x3
83 #define STREAM_MEM_HANDLE_TYPE_SHM 0x4
84 #define STREAM_MEM_HANDLE_TYPE_ZIRCON 0x5
85 #define STREAM_FENCE_HANDLE_TYPE_OPAQUE_FD 0x6
86 #define STREAM_FENCE_HANDLE_TYPE_SYNC_FD 0x7
87 #define STREAM_FENCE_HANDLE_TYPE_OPAQUE_WIN32 0x8
88 #define STREAM_FENCE_HANDLE_TYPE_ZIRCON 0x9
89 struct stream_renderer_handle {
90     int64_t os_handle;
91     uint32_t handle_type;
92 };
93 
94 // @user_data: custom user data passed during `stream_renderer_init`
95 // @type: one of STREAM_RENDERER_DEBUG_*
96 // @string: null-terminated C-string
97 #define STREAM_RENDERER_DEBUG_ERROR 0x1
98 #define STREAM_RENDERER_DEBUG_WARN 0x2
99 #define STREAM_RENDERER_DEBUG_INFO 0x3
100 #define STREAM_RENDERER_DEBUG_DEBUG 0x4
101 struct stream_renderer_debug {
102     uint32_t debug_type;
103     const char* message;
104 };
105 
106 // Log level of gfxstream
107 #ifndef STREAM_RENDERER_LOG_LEVEL
108 #define STREAM_RENDERER_LOG_LEVEL STREAM_RENDERER_DEBUG_INFO
109 #endif
110 
111 void stream_renderer_log(uint32_t type, const char* file, int line, const char* pretty_function,
112                          const char* format, ...);
113 
114 #if STREAM_RENDERER_LOG_LEVEL >= STREAM_RENDERER_DEBUG_ERROR
115 #define stream_renderer_error(format, ...)                                                        \
116     do {                                                                                          \
117         stream_renderer_log(STREAM_RENDERER_DEBUG_ERROR, __FILE__, __LINE__, __PRETTY_FUNCTION__, \
118                             format, ##__VA_ARGS__);                                               \
119     } while (0)
120 #else
121 #define stream_renderer_error(format, ...)
122 #endif
123 
124 #if STREAM_RENDERER_LOG_LEVEL >= STREAM_RENDERER_DEBUG_WARN
125 #define stream_renderer_warn(format, ...)                                                        \
126     do {                                                                                         \
127         stream_renderer_log(STREAM_RENDERER_DEBUG_WARN, __FILE__, __LINE__, __PRETTY_FUNCTION__, \
128                             format, ##__VA_ARGS__);                                              \
129     } while (0)
130 #else
131 #define stream_renderer_warn(format, ...)
132 #endif
133 
134 #if STREAM_RENDERER_LOG_LEVEL >= STREAM_RENDERER_DEBUG_INFO
135 #define stream_renderer_info(format, ...)                                                         \
136     do {                                                                                          \
137         stream_renderer_log(STREAM_RENDERER_DEBUG_INFO, __FILE__, __LINE__, __FUNCTION__, format, \
138                             ##__VA_ARGS__);                                                       \
139     } while (0)
140 #else
141 #define stream_renderer_info(format, ...)
142 #endif
143 
144 #if STREAM_RENDERER_LOG_LEVEL >= STREAM_RENDERER_DEBUG_DEBUG
145 #define stream_renderer_debug(format, ...)                                                        \
146     do {                                                                                          \
147         stream_renderer_log(STREAM_RENDERER_DEBUG_DEBUG, __FILE__, __LINE__, __PRETTY_FUNCTION__, \
148                             format, ##__VA_ARGS__);                                               \
149     } while (0)
150 #else
151 #define stream_renderer_debug(format, ...)
152 #endif
153 
154 // Callback for writing a fence.
155 typedef void (*stream_renderer_fence_callback)(void* user_data,
156                                                struct stream_renderer_fence* fence_data);
157 
158 // Callback for allowing debug prints or possibly even aborts.
159 typedef void (*stream_renderer_debug_callback)(void* user_data,
160                                                struct stream_renderer_debug* debug);
161 
162 // Parameters - data passed to initialize the renderer, with the goal of avoiding FFI breakages.
163 // To change the data a parameter is passing safely, you should create a new parameter and
164 // deprecate the old one. The old parameter may be removed after sufficient time.
165 //
166 // STREAM_RENDERER_PARAM_NULL: Reserved value
167 //
168 // The following are required for correct operation:
169 // STREAM_RENDERER_PARAM_USER_DATA: User data, for custom use by VMM.
170 // STREAM_RENDERER_PARAM_RENDERER_FLAGS: Bitwise flags for the renderer.
171 // STREAM_RENDERER_PARAM_FENCE_CALLBACK: A function of the type `stream_renderer_fence_callback`
172 
173 // The following are optional:
174 // STREAM_RENDERER_PARAM_WIN0_WIDTH: The width of window[0], when using surface-based rendering
175 // STREAM_RENDERER_PARAM_WIN0_HEIGHT: The height of window[0], when using surface-based rendering
176 #define STREAM_RENDERER_PARAM_NULL 0
177 #define STREAM_RENDERER_PARAM_USER_DATA 1
178 #define STREAM_RENDERER_PARAM_RENDERER_FLAGS 2
179 #define STREAM_RENDERER_PARAM_FENCE_CALLBACK 3
180 #define STREAM_RENDERER_PARAM_WIN0_WIDTH 4
181 #define STREAM_RENDERER_PARAM_WIN0_HEIGHT 5
182 #define STREAM_RENDERER_PARAM_DEBUG_CALLBACK 6
183 
184 // An entry in the stream renderer parameters list.
185 // The key should be one of STREAM_RENDERER_PARAM_*
186 // The value can be either a uint64_t or cast to a pointer to a struct, depending on if the
187 // parameter needs to pass data bigger than a single uint64_t.
188 struct stream_renderer_param {
189     uint64_t key;
190     uint64_t value;
191 };
192 
193 // Entry point for the stream renderer.
194 // Pass a list of parameters to configure the renderer. The available ones are listed above. If a
195 // parameter is not supported, the renderer will ignore it and warn in stderr.
196 // Return value 0 indicates success, and a negative number indicates failure.
197 VG_EXPORT int stream_renderer_init(struct stream_renderer_param* stream_renderer_params,
198                                    uint64_t num_params);
199 
200 VG_EXPORT void stream_renderer_teardown(void);
201 
202 VG_EXPORT int stream_renderer_resource_create(struct stream_renderer_resource_create_args* args,
203                                               struct iovec* iov, uint32_t num_iovs);
204 
205 VG_EXPORT void stream_renderer_resource_unref(uint32_t res_handle);
206 VG_EXPORT void stream_renderer_context_destroy(uint32_t handle);
207 
208 struct stream_renderer_command {
209     uint32_t ctx_id;
210     uint32_t cmd_size;
211     uint8_t* cmd;
212 
213     // Unstable: do not use until release strictly greater than 0.1.2
214     uint32_t num_in_fences;
215     struct stream_renderer_handle* fences;
216 };
217 
218 VG_EXPORT int stream_renderer_submit_cmd(struct stream_renderer_command* cmd);
219 
220 VG_EXPORT int stream_renderer_transfer_read_iov(uint32_t handle, uint32_t ctx_id, uint32_t level,
221                                                 uint32_t stride, uint32_t layer_stride,
222                                                 struct stream_renderer_box* box, uint64_t offset,
223                                                 struct iovec* iov, int iovec_cnt);
224 VG_EXPORT int stream_renderer_transfer_write_iov(uint32_t handle, uint32_t ctx_id, int level,
225                                                  uint32_t stride, uint32_t layer_stride,
226                                                  struct stream_renderer_box* box, uint64_t offset,
227                                                  struct iovec* iovec, unsigned int iovec_cnt);
228 VG_EXPORT void stream_renderer_get_cap_set(uint32_t set, uint32_t* max_ver, uint32_t* max_size);
229 VG_EXPORT void stream_renderer_fill_caps(uint32_t set, uint32_t version, void* caps);
230 
231 VG_EXPORT int stream_renderer_resource_attach_iov(int res_handle, struct iovec* iov, int num_iovs);
232 VG_EXPORT void stream_renderer_resource_detach_iov(int res_handle, struct iovec** iov,
233                                                    int* num_iovs);
234 VG_EXPORT void stream_renderer_ctx_attach_resource(int ctx_id, int res_handle);
235 VG_EXPORT void stream_renderer_ctx_detach_resource(int ctx_id, int res_handle);
236 
237 struct stream_renderer_create_blob {
238     uint32_t blob_mem;
239     uint32_t blob_flags;
240     uint64_t blob_id;
241     uint64_t size;
242 };
243 
244 #define STREAM_BLOB_MEM_GUEST 1
245 #define STREAM_BLOB_MEM_HOST3D 2
246 #define STREAM_BLOB_MEM_HOST3D_GUEST 3
247 
248 #define STREAM_BLOB_FLAG_USE_MAPPABLE 1
249 #define STREAM_BLOB_FLAG_USE_SHAREABLE 2
250 #define STREAM_BLOB_FLAG_USE_CROSS_DEVICE 4
251 #define STREAM_BLOB_FLAG_CREATE_GUEST_HANDLE 8
252 
253 VG_EXPORT int stream_renderer_create_blob(uint32_t ctx_id, uint32_t res_handle,
254                                           const struct stream_renderer_create_blob* create_blob,
255                                           const struct iovec* iovecs, uint32_t num_iovs,
256                                           const struct stream_renderer_handle* handle);
257 
258 VG_EXPORT int stream_renderer_export_blob(uint32_t res_handle,
259                                           struct stream_renderer_handle* handle);
260 
261 VG_EXPORT int stream_renderer_resource_map(uint32_t res_handle, void** hvaOut, uint64_t* sizeOut);
262 VG_EXPORT int stream_renderer_resource_unmap(uint32_t res_handle);
263 
264 VG_EXPORT int stream_renderer_context_create(uint32_t ctx_id, uint32_t nlen, const char* name,
265                                              uint32_t context_init);
266 
267 VG_EXPORT int stream_renderer_create_fence(const struct stream_renderer_fence* fence);
268 
269 #define STREAM_RENDERER_MAP_CACHE_MASK 0x0f
270 #define STREAM_RENDERER_MAP_CACHE_NONE 0x00
271 #define STREAM_RENDERER_MAP_CACHE_CACHED 0x01
272 #define STREAM_RENDERER_MAP_CACHE_UNCACHED 0x02
273 #define STREAM_RENDERER_MAP_CACHE_WC 0x03
274 VG_EXPORT int stream_renderer_resource_map_info(uint32_t res_handle, uint32_t* map_info);
275 
276 // Unique identifier for a GPU device.
277 struct stream_renderer_device_id {
278     uint8_t device_uuid[16];
279     uint8_t driver_uuid[16];
280 };
281 
282 struct stream_renderer_vulkan_info {
283     uint32_t memory_index;
284     struct stream_renderer_device_id device_id;
285 };
286 
287 VG_EXPORT int stream_renderer_vulkan_info(uint32_t res_handle,
288                                           struct stream_renderer_vulkan_info* vulkan_info);
289 
290 #ifdef __cplusplus
291 }  // extern "C"
292 #endif
293 
294 // based on VIRGL_RENDERER_USE* and friends
295 enum RendererFlags {
296     STREAM_RENDERER_FLAGS_USE_EGL_BIT = 1 << 0,
297     STREAM_RENDERER_FLAGS_THREAD_SYNC = 1 << 1,
298     STREAM_RENDERER_FLAGS_USE_GLX_BIT = 1 << 2,
299     STREAM_RENDERER_FLAGS_USE_SURFACELESS_BIT = 1 << 3,
300     STREAM_RENDERER_FLAGS_USE_GLES_BIT = 1 << 4,
301     STREAM_RENDERER_FLAGS_USE_VK_BIT = 1 << 5,
302     STREAM_RENDERER_FLAGS_USE_EXTERNAL_BLOB = 1 << 6,
303     STREAM_RENDERER_FLAGS_USE_SYSTEM_BLOB = 1 << 7,
304     STREAM_RENDERER_FLAGS_VULKAN_NATIVE_SWAPCHAIN_BIT = 1 << 8,
305     // Unstable: do not use until a release greater than 0.1.2
306     STREAM_RENDERER_FLAGS_VULKAN_EXTERNAL_SYNC = 1 << 31,
307 };
308 
309 #endif
310