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 #ifndef VREND_RENDERER_H
26 #define VREND_RENDERER_H
27
28 #include "pipe/p_state.h"
29 #include "util/u_double_list.h"
30 #include "util/u_inlines.h"
31 #include "virgl_protocol.h"
32 #include "vrend_debug.h"
33 #include "vrend_tweaks.h"
34 #include "vrend_iov.h"
35 #include "vrend_winsys_gbm.h"
36 #include "virgl_hw.h"
37 #include <epoxy/gl.h>
38
39 typedef void *virgl_gl_context;
40 typedef void *virgl_gl_drawable;
41
42 struct virgl_gl_ctx_param {
43 int major_ver;
44 int minor_ver;
45 bool shared;
46 };
47
48 struct virgl_context;
49 struct virgl_resource;
50 struct vrend_context;
51
52 /* Number of mipmap levels for which to keep the backing iov offsets.
53 * Value mirrored from mesa/virgl
54 */
55 #define VR_MAX_TEXTURE_2D_LEVELS 15
56
57 #define VREND_STORAGE_GUEST_MEMORY BIT(0)
58 #define VREND_STORAGE_GL_TEXTURE BIT(1)
59 #define VREND_STORAGE_GL_BUFFER BIT(2)
60 #define VREND_STORAGE_EGL_IMAGE BIT(3)
61 #define VREND_STORAGE_GBM_BUFFER BIT(4)
62 #define VREND_STORAGE_HOST_SYSTEM_MEMORY BIT(5)
63 #define VREND_STORAGE_GL_IMMUTABLE BIT(6)
64 #define VREND_STORAGE_GL_MEMOBJ BIT(7)
65
66 struct vrend_resource {
67 struct pipe_resource base;
68 uint32_t storage_bits;
69 uint32_t map_info;
70
71 GLuint id;
72 GLenum target;
73
74 GLuint tbo_tex_id;/* tbos have two ids to track */
75 bool y_0_top;
76
77 /* Pointer to system memory storage for this resource. Only valid for
78 * VREND_RESOURCE_STORAGE_GUEST_ELSE_SYSTEM buffer storage.
79 */
80 char *ptr;
81 /* IOV pointing to shared guest memory storage for this resource. */
82 const struct iovec *iov;
83 uint32_t num_iovs;
84 uint64_t mipmap_offsets[VR_MAX_TEXTURE_2D_LEVELS];
85 void *gbm_bo, *egl_image;
86 void *aux_plane_egl_image[VIRGL_GBM_MAX_PLANES];
87
88 uint64_t size;
89 GLbitfield buffer_storage_flags;
90 GLuint memobj;
91
92 uint32_t blob_id;
93 struct list_head head;
94 };
95
96 #define VIRGL_TEXTURE_NEED_SWIZZLE (1 << 0)
97 #define VIRGL_TEXTURE_CAN_TEXTURE_STORAGE (1 << 1)
98 #define VIRGL_TEXTURE_CAN_READBACK (1 << 2)
99
100 struct vrend_format_table {
101 enum virgl_formats format;
102 GLenum internalformat;
103 GLenum glformat;
104 GLenum gltype;
105 uint8_t swizzle[4];
106 uint32_t bindings;
107 uint32_t flags;
108 };
109
110 typedef void (*vrend_context_fence_retire)(void *fence_cookie,
111 void *retire_data);
112
113 struct vrend_if_cbs {
114 vrend_context_fence_retire ctx0_fence_retire;
115
116 virgl_gl_context (*create_gl_context)(int scanout, struct virgl_gl_ctx_param *params);
117 void (*destroy_gl_context)(virgl_gl_context ctx);
118 int (*make_current)(virgl_gl_context ctx);
119 };
120
121 #define VREND_USE_THREAD_SYNC 1
122 #define VREND_USE_EXTERNAL_BLOB 2
123
124 const struct virgl_resource_pipe_callbacks *
125 vrend_renderer_get_pipe_callbacks(void);
126
127 int vrend_renderer_init(const struct vrend_if_cbs *cbs, uint32_t flags);
128
129 void vrend_insert_format(struct vrend_format_table *entry, uint32_t bindings, uint32_t flags);
130 bool vrend_check_framebuffer_mixed_color_attachements(void);
131
132 void vrend_insert_format_swizzle(int override_format, struct vrend_format_table *entry,
133 uint32_t bindings, uint8_t swizzle[4], uint32_t flags);
134 const struct vrend_format_table *vrend_get_format_table_entry(enum virgl_formats format);
135 const struct vrend_format_table *vrend_get_format_table_entry_with_emulation(uint32_t bind, enum virgl_formats format);
136
137 int vrend_create_shader(struct vrend_context *ctx,
138 uint32_t handle,
139 const struct pipe_stream_output_info *stream_output,
140 uint32_t req_local_mem,
141 const char *shd_text, uint32_t offlen, uint32_t num_tokens,
142 uint32_t type, uint32_t pkt_length);
143
144 void vrend_bind_shader(struct vrend_context *ctx,
145 uint32_t type,
146 uint32_t handle);
147
148 void vrend_bind_vs_so(struct vrend_context *ctx,
149 uint32_t handle);
150 void vrend_clear(struct vrend_context *ctx,
151 unsigned buffers,
152 const union pipe_color_union *color,
153 double depth, unsigned stencil);
154
155 void vrend_clear_texture(struct vrend_context* ctx,
156 uint32_t handle, uint32_t level,
157 const struct pipe_box *box,
158 const void * data);
159
160 int vrend_draw_vbo(struct vrend_context *ctx,
161 const struct pipe_draw_info *info,
162 uint32_t cso, uint32_t indirect_handle, uint32_t indirect_draw_count_handle);
163
164 void vrend_set_framebuffer_state(struct vrend_context *ctx,
165 uint32_t nr_cbufs, uint32_t surf_handle[PIPE_MAX_COLOR_BUFS],
166 uint32_t zsurf_handle);
167
168 struct vrend_context *vrend_create_context(int id, uint32_t nlen, const char *debug_name);
169 void vrend_destroy_context(struct vrend_context *ctx);
170 struct virgl_context *vrend_renderer_context_create(uint32_t handle,
171 uint32_t nlen,
172 const char *name);
173
174 struct vrend_renderer_resource_create_args {
175 enum pipe_texture_target target;
176 uint32_t format;
177 uint32_t bind;
178 uint32_t width;
179 uint32_t height;
180 uint32_t depth;
181 uint32_t array_size;
182 uint32_t last_level;
183 uint32_t nr_samples;
184 uint32_t flags;
185 };
186
187 /* set the type info of an untyped blob resource */
188 struct vrend_renderer_resource_set_type_args {
189 uint32_t format;
190 uint32_t bind;
191 uint32_t width;
192 uint32_t height;
193 uint32_t usage;
194 uint64_t modifier;
195 uint32_t plane_count;
196 uint32_t plane_strides[VIRGL_GBM_MAX_PLANES];
197 uint32_t plane_offsets[VIRGL_GBM_MAX_PLANES];
198 };
199
200 struct pipe_resource *
201 vrend_renderer_resource_create(const struct vrend_renderer_resource_create_args *args,
202 void *image_eos);
203
204 int vrend_create_surface(struct vrend_context *ctx,
205 uint32_t handle,
206 uint32_t res_handle, uint32_t format,
207 uint32_t val0, uint32_t val1);
208 int vrend_create_sampler_view(struct vrend_context *ctx,
209 uint32_t handle,
210 uint32_t res_handle, uint32_t format,
211 uint32_t val0, uint32_t val1, uint32_t swizzle_packed);
212
213 int vrend_create_sampler_state(struct vrend_context *ctx,
214 uint32_t handle,
215 struct pipe_sampler_state *templ);
216
217 int vrend_create_so_target(struct vrend_context *ctx,
218 uint32_t handle,
219 uint32_t res_handle,
220 uint32_t buffer_offset,
221 uint32_t buffer_size);
222
223 void vrend_set_streamout_targets(struct vrend_context *ctx,
224 uint32_t append_bitmask,
225 uint32_t num_targets,
226 uint32_t *handles);
227
228 int vrend_create_vertex_elements_state(struct vrend_context *ctx,
229 uint32_t handle,
230 unsigned num_elements,
231 const struct pipe_vertex_element *elements);
232 void vrend_bind_vertex_elements_state(struct vrend_context *ctx,
233 uint32_t handle);
234
235 void vrend_set_single_vbo(struct vrend_context *ctx,
236 uint32_t index,
237 uint32_t stride,
238 uint32_t buffer_offset,
239 uint32_t res_handle);
240 void vrend_set_num_vbo(struct vrend_context *ctx,
241 int num_vbo);
242
243 int vrend_transfer_inline_write(struct vrend_context *ctx,
244 uint32_t dst_handle,
245 const struct vrend_transfer_info *info);
246
247 int vrend_renderer_copy_transfer3d(struct vrend_context *ctx,
248 uint32_t dst_handle,
249 uint32_t src_handle,
250 const struct vrend_transfer_info *info);
251
252 void vrend_set_viewport_states(struct vrend_context *ctx,
253 uint32_t start_slot, uint32_t num_viewports,
254 const struct pipe_viewport_state *state);
255 void vrend_set_num_sampler_views(struct vrend_context *ctx,
256 uint32_t shader_type,
257 uint32_t start_slot,
258 uint32_t num_sampler_views);
259 void vrend_set_single_sampler_view(struct vrend_context *ctx,
260 uint32_t shader_type,
261 uint32_t index,
262 uint32_t res_handle);
263
264 void vrend_object_bind_blend(struct vrend_context *ctx,
265 uint32_t handle);
266 void vrend_object_bind_dsa(struct vrend_context *ctx,
267 uint32_t handle);
268 void vrend_object_bind_rasterizer(struct vrend_context *ctx,
269 uint32_t handle);
270
271 void vrend_bind_sampler_states(struct vrend_context *ctx,
272 uint32_t shader_type,
273 uint32_t start_slot,
274 uint32_t num_states,
275 const uint32_t *handles);
276 void vrend_set_index_buffer(struct vrend_context *ctx,
277 uint32_t res_handle,
278 uint32_t index_size,
279 uint32_t offset);
280 void vrend_set_single_image_view(struct vrend_context *ctx,
281 uint32_t shader_type,
282 uint32_t index,
283 uint32_t format, uint32_t access,
284 uint32_t layer_offset, uint32_t level_size,
285 uint32_t handle);
286 void vrend_set_single_ssbo(struct vrend_context *ctx,
287 uint32_t shader_type,
288 uint32_t index,
289 uint32_t offset, uint32_t length,
290 uint32_t handle);
291 void vrend_set_single_abo(struct vrend_context *ctx,
292 uint32_t index,
293 uint32_t offset, uint32_t length,
294 uint32_t handle);
295 void vrend_memory_barrier(struct vrend_context *ctx,
296 unsigned flags);
297 void vrend_launch_grid(struct vrend_context *ctx,
298 uint32_t *block,
299 uint32_t *grid,
300 uint32_t indirect_handle,
301 uint32_t indirect_offset);
302 void vrend_set_framebuffer_state_no_attach(struct vrend_context *ctx,
303 uint32_t width, uint32_t height,
304 uint32_t layers, uint32_t samples);
305 void vrend_texture_barrier(struct vrend_context *ctx,
306 unsigned flags);
307
308 int vrend_renderer_transfer_iov(struct vrend_context *ctx,
309 uint32_t dst_handle,
310 const struct vrend_transfer_info *info,
311 int transfer_mode);
312
313 int vrend_renderer_transfer_pipe(struct pipe_resource *pres,
314 const struct vrend_transfer_info *info,
315 int transfer_mode);
316
317 void vrend_renderer_resource_copy_region(struct vrend_context *ctx,
318 uint32_t dst_handle, uint32_t dst_level,
319 uint32_t dstx, uint32_t dsty, uint32_t dstz,
320 uint32_t src_handle, uint32_t src_level,
321 const struct pipe_box *src_box);
322
323 void vrend_renderer_blit(struct vrend_context *ctx,
324 uint32_t dst_handle, uint32_t src_handle,
325 const struct pipe_blit_info *info);
326
327 void vrend_set_stencil_ref(struct vrend_context *ctx, struct pipe_stencil_ref *ref);
328 void vrend_set_blend_color(struct vrend_context *ctx, struct pipe_blend_color *color);
329 void vrend_set_scissor_state(struct vrend_context *ctx,
330 uint32_t start_slot,
331 uint32_t num_scissor,
332 struct pipe_scissor_state *ss);
333
334 void vrend_set_polygon_stipple(struct vrend_context *ctx, struct pipe_poly_stipple *ps);
335
336 void vrend_set_clip_state(struct vrend_context *ctx, struct pipe_clip_state *ucp);
337 void vrend_set_sample_mask(struct vrend_context *ctx, unsigned sample_mask);
338 void vrend_set_min_samples(struct vrend_context *ctx, unsigned min_samples);
339
340 void vrend_set_constants(struct vrend_context *ctx,
341 uint32_t shader,
342 uint32_t num_constant,
343 const float *data);
344
345 void vrend_set_uniform_buffer(struct vrend_context *ctx, uint32_t shader,
346 uint32_t index, uint32_t offset, uint32_t length,
347 uint32_t res_handle);
348
349 void vrend_fb_bind_texture_id(struct vrend_resource *res,
350 int id,
351 int idx,
352 uint32_t level, uint32_t layer);
353
354 void vrend_set_tess_state(struct vrend_context *ctx, const float tess_factors[6]);
355
356 void vrend_renderer_fini(void);
357
358 void vrend_renderer_set_fence_retire(struct vrend_context *ctx,
359 vrend_context_fence_retire retire,
360 void *retire_data);
361
362 int vrend_renderer_create_fence(struct vrend_context *ctx,
363 uint32_t flags,
364 void *fence_cookie);
365
366 void vrend_renderer_check_fences(void);
367
368 int vrend_renderer_create_ctx0_fence(uint32_t fence_id);
369 int vrend_renderer_export_ctx0_fence(uint32_t fence_id, int* out_fd);
370
371 bool vrend_hw_switch_context(struct vrend_context *ctx, bool now);
372 uint32_t vrend_renderer_object_insert(struct vrend_context *ctx, void *data,
373 uint32_t handle, enum virgl_object_type type);
374 void vrend_renderer_object_destroy(struct vrend_context *ctx, uint32_t handle);
375
376 int vrend_create_query(struct vrend_context *ctx, uint32_t handle,
377 uint32_t query_type, uint32_t query_index,
378 uint32_t res_handle, uint32_t offset);
379
380 int vrend_begin_query(struct vrend_context *ctx, uint32_t handle);
381 int vrend_end_query(struct vrend_context *ctx, uint32_t handle);
382 void vrend_get_query_result(struct vrend_context *ctx, uint32_t handle,
383 uint32_t wait);
384 void vrend_get_query_result_qbo(struct vrend_context *ctx, uint32_t handle,
385 uint32_t qbo_handle,
386 uint32_t wait, uint32_t result_type, uint32_t offset,
387 int32_t index);
388 void vrend_render_condition(struct vrend_context *ctx,
389 uint32_t handle,
390 bool condtion,
391 uint mode);
392 void *vrend_renderer_get_cursor_contents(struct pipe_resource *pres,
393 uint32_t *width,
394 uint32_t *height);
395
396 void vrend_renderer_fill_caps(uint32_t set, uint32_t version,
397 union virgl_caps *caps);
398
399 GLint64 vrend_renderer_get_timestamp(void);
400
401 void vrend_build_format_list_common(void);
402 void vrend_build_format_list_gl(void);
403 void vrend_build_format_list_gles(void);
404 void vrend_build_emulated_format_list_gles(void);
405 void vrend_check_texture_storage(struct vrend_format_table *table);
406
407 void vrend_renderer_resource_destroy(struct vrend_resource *res);
408
409 static inline void
vrend_resource_reference(struct vrend_resource ** ptr,struct vrend_resource * tex)410 vrend_resource_reference(struct vrend_resource **ptr, struct vrend_resource *tex)
411 {
412 struct vrend_resource *old_tex = *ptr;
413
414 if (pipe_reference(&(*ptr)->base.reference, &tex->base.reference))
415 vrend_renderer_resource_destroy(old_tex);
416 *ptr = tex;
417 }
418
419 void vrend_renderer_force_ctx_0(void);
420
421 void vrend_renderer_get_rect(struct pipe_resource *pres,
422 const struct iovec *iov, unsigned int num_iovs,
423 uint32_t offset,
424 int x, int y, int width, int height);
425
426 void vrend_renderer_attach_res_ctx(struct vrend_context *ctx,
427 struct virgl_resource *res);
428 void vrend_renderer_detach_res_ctx(struct vrend_context *ctx,
429 struct virgl_resource *res);
430
431 struct vrend_context_tweaks *vrend_get_context_tweaks(struct vrend_context *ctx);
432
433 struct vrend_renderer_resource_info {
434 uint32_t handle;
435 uint32_t format;
436 uint32_t width;
437 uint32_t height;
438 uint32_t depth;
439 uint32_t flags;
440 uint32_t tex_id;
441 uint32_t stride;
442 };
443
444 void vrend_renderer_resource_get_info(struct pipe_resource *pres,
445 struct vrend_renderer_resource_info *info);
446
447 void vrend_renderer_get_cap_set(uint32_t cap_set, uint32_t *max_ver,
448 uint32_t *max_size);
449
450 void vrend_renderer_create_sub_ctx(struct vrend_context *ctx, int sub_ctx_id);
451 void vrend_renderer_destroy_sub_ctx(struct vrend_context *ctx, int sub_ctx_id);
452 void vrend_renderer_set_sub_ctx(struct vrend_context *ctx, int sub_ctx_id);
453
454 void vrend_report_context_error_internal(const char *fname, struct vrend_context *ctx,
455 enum virgl_ctx_errors error, uint32_t value);
456
457 #define vrend_report_context_error(ctx, error, value) \
458 vrend_report_context_error_internal(__func__, ctx, error, value)
459
460 #define vrend_report_buffer_error(ctx, cmd) \
461 vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_CMD_BUFFER, cmd)
462
463 void vrend_fb_bind_texture(struct vrend_resource *res,
464 int idx,
465 uint32_t level, uint32_t layer);
466 bool vrend_format_is_emulated_alpha(enum virgl_formats format);
467 boolean format_is_copy_compatible(enum virgl_formats src, enum virgl_formats dst,
468 boolean allow_compressed);
469
470 /* blitter interface */
471 void vrend_renderer_blit_gl(struct vrend_context *ctx,
472 struct vrend_resource *src_res,
473 struct vrend_resource *dst_res,
474 GLenum blit_views[2],
475 const struct pipe_blit_info *info,
476 bool has_texture_srgb_decode,
477 bool has_srgb_write_control,
478 bool skip_dest_swizzle);
479 void vrend_blitter_fini(void);
480
481 void vrend_renderer_prepare_reset(void);
482 void vrend_renderer_reset(void);
483 int vrend_renderer_get_poll_fd(void);
484
485 unsigned vrend_context_has_debug_flag(const struct vrend_context *ctx,
486 enum virgl_debug_flags flag);
487
488 unsigned vrend_renderer_query_multisample_caps(unsigned max_samples,
489 struct virgl_caps_v2 *caps);
490
491 struct gl_version {
492 uint32_t major;
493 uint32_t minor;
494 };
495
496 static const struct gl_version gl_versions[] = { {4,6}, {4,5}, {4,4}, {4,3}, {4,2}, {4,1}, {4,0},
497 {3,3}, {3,2}, {3,1}, {3,0} };
498
499 extern const struct vrend_if_cbs *vrend_clicbs;
500
501 int vrend_renderer_export_query(struct pipe_resource *pres,
502 struct virgl_renderer_export_query *export_query);
503
504 void vrend_sync_make_current(virgl_gl_context);
505
506 int
507 vrend_renderer_pipe_resource_create(struct vrend_context *ctx, uint32_t blob_id,
508 const struct vrend_renderer_resource_create_args *args);
509
510 struct pipe_resource *vrend_get_blob_pipe(struct vrend_context *ctx, uint64_t blob_id);
511
512 int
513 vrend_renderer_pipe_resource_set_type(struct vrend_context *ctx,
514 uint32_t res_id,
515 const struct vrend_renderer_resource_set_type_args *args);
516
517 uint32_t vrend_renderer_resource_get_map_info(struct pipe_resource *pres);
518
519 int vrend_renderer_resource_map(struct pipe_resource *pres, void **map, uint64_t *out_size);
520
521 int vrend_renderer_resource_unmap(struct pipe_resource *pres);
522
523 void vrend_renderer_get_meminfo(struct vrend_context *ctx, uint32_t res_handle);
524 #endif
525