1*bbecb9d1SAndroid Build Coastguard Worker /*
2*bbecb9d1SAndroid Build Coastguard Worker * Copyright 2021 Google LLC
3*bbecb9d1SAndroid Build Coastguard Worker * SPDX-License-Identifier: MIT
4*bbecb9d1SAndroid Build Coastguard Worker */
5*bbecb9d1SAndroid Build Coastguard Worker
6*bbecb9d1SAndroid Build Coastguard Worker #include "render_virgl.h"
7*bbecb9d1SAndroid Build Coastguard Worker
8*bbecb9d1SAndroid Build Coastguard Worker #include "virglrenderer.h"
9*bbecb9d1SAndroid Build Coastguard Worker
10*bbecb9d1SAndroid Build Coastguard Worker #include "render_context.h"
11*bbecb9d1SAndroid Build Coastguard Worker
12*bbecb9d1SAndroid Build Coastguard Worker struct render_virgl render_virgl_internal = {
13*bbecb9d1SAndroid Build Coastguard Worker #ifdef ENABLE_RENDER_SERVER_WORKER_THREAD
14*bbecb9d1SAndroid Build Coastguard Worker .struct_mutex = _MTX_INITIALIZER_NP,
15*bbecb9d1SAndroid Build Coastguard Worker .dispatch_mutex = _MTX_INITIALIZER_NP,
16*bbecb9d1SAndroid Build Coastguard Worker #endif
17*bbecb9d1SAndroid Build Coastguard Worker .init_count = 0,
18*bbecb9d1SAndroid Build Coastguard Worker };
19*bbecb9d1SAndroid Build Coastguard Worker
20*bbecb9d1SAndroid Build Coastguard Worker static struct render_virgl *
render_virgl_lock_struct(void)21*bbecb9d1SAndroid Build Coastguard Worker render_virgl_lock_struct(void)
22*bbecb9d1SAndroid Build Coastguard Worker {
23*bbecb9d1SAndroid Build Coastguard Worker #ifdef ENABLE_RENDER_SERVER_WORKER_THREAD
24*bbecb9d1SAndroid Build Coastguard Worker mtx_lock(&render_virgl_internal.struct_mutex);
25*bbecb9d1SAndroid Build Coastguard Worker #endif
26*bbecb9d1SAndroid Build Coastguard Worker return &render_virgl_internal;
27*bbecb9d1SAndroid Build Coastguard Worker }
28*bbecb9d1SAndroid Build Coastguard Worker
29*bbecb9d1SAndroid Build Coastguard Worker static void
render_virgl_unlock_struct(void)30*bbecb9d1SAndroid Build Coastguard Worker render_virgl_unlock_struct(void)
31*bbecb9d1SAndroid Build Coastguard Worker {
32*bbecb9d1SAndroid Build Coastguard Worker #ifdef ENABLE_RENDER_SERVER_WORKER_THREAD
33*bbecb9d1SAndroid Build Coastguard Worker mtx_unlock(&render_virgl_internal.struct_mutex);
34*bbecb9d1SAndroid Build Coastguard Worker #endif
35*bbecb9d1SAndroid Build Coastguard Worker }
36*bbecb9d1SAndroid Build Coastguard Worker
37*bbecb9d1SAndroid Build Coastguard Worker static struct render_context *
render_virgl_lookup_context(uint32_t ctx_id)38*bbecb9d1SAndroid Build Coastguard Worker render_virgl_lookup_context(uint32_t ctx_id)
39*bbecb9d1SAndroid Build Coastguard Worker {
40*bbecb9d1SAndroid Build Coastguard Worker const struct render_virgl *virgl = render_virgl_lock_struct();
41*bbecb9d1SAndroid Build Coastguard Worker struct render_context *ctx = NULL;
42*bbecb9d1SAndroid Build Coastguard Worker
43*bbecb9d1SAndroid Build Coastguard Worker #ifdef ENABLE_RENDER_SERVER_WORKER_THREAD
44*bbecb9d1SAndroid Build Coastguard Worker list_for_each_entry (struct render_context, iter, &virgl->contexts, head) {
45*bbecb9d1SAndroid Build Coastguard Worker if (iter->ctx_id == ctx_id) {
46*bbecb9d1SAndroid Build Coastguard Worker ctx = iter;
47*bbecb9d1SAndroid Build Coastguard Worker break;
48*bbecb9d1SAndroid Build Coastguard Worker }
49*bbecb9d1SAndroid Build Coastguard Worker }
50*bbecb9d1SAndroid Build Coastguard Worker #else
51*bbecb9d1SAndroid Build Coastguard Worker assert(list_is_singular(&virgl->contexts));
52*bbecb9d1SAndroid Build Coastguard Worker ctx = list_first_entry(&virgl->contexts, struct render_context, head);
53*bbecb9d1SAndroid Build Coastguard Worker assert(ctx->ctx_id == ctx_id);
54*bbecb9d1SAndroid Build Coastguard Worker (void)ctx_id;
55*bbecb9d1SAndroid Build Coastguard Worker #endif
56*bbecb9d1SAndroid Build Coastguard Worker
57*bbecb9d1SAndroid Build Coastguard Worker render_virgl_unlock_struct();
58*bbecb9d1SAndroid Build Coastguard Worker
59*bbecb9d1SAndroid Build Coastguard Worker return ctx;
60*bbecb9d1SAndroid Build Coastguard Worker }
61*bbecb9d1SAndroid Build Coastguard Worker
62*bbecb9d1SAndroid Build Coastguard Worker static void
render_virgl_debug_callback(const char * fmt,va_list ap)63*bbecb9d1SAndroid Build Coastguard Worker render_virgl_debug_callback(const char *fmt, va_list ap)
64*bbecb9d1SAndroid Build Coastguard Worker {
65*bbecb9d1SAndroid Build Coastguard Worker char buf[1024];
66*bbecb9d1SAndroid Build Coastguard Worker vsnprintf(buf, sizeof(buf), fmt, ap);
67*bbecb9d1SAndroid Build Coastguard Worker render_log(buf);
68*bbecb9d1SAndroid Build Coastguard Worker }
69*bbecb9d1SAndroid Build Coastguard Worker
70*bbecb9d1SAndroid Build Coastguard Worker static void
render_virgl_cb_write_context_fence(UNUSED void * cookie,uint32_t ctx_id,uint32_t ring_idx,uint64_t fence_id)71*bbecb9d1SAndroid Build Coastguard Worker render_virgl_cb_write_context_fence(UNUSED void *cookie,
72*bbecb9d1SAndroid Build Coastguard Worker uint32_t ctx_id,
73*bbecb9d1SAndroid Build Coastguard Worker uint32_t ring_idx,
74*bbecb9d1SAndroid Build Coastguard Worker uint64_t fence_id)
75*bbecb9d1SAndroid Build Coastguard Worker {
76*bbecb9d1SAndroid Build Coastguard Worker struct render_context *ctx = render_virgl_lookup_context(ctx_id);
77*bbecb9d1SAndroid Build Coastguard Worker assert(ctx);
78*bbecb9d1SAndroid Build Coastguard Worker
79*bbecb9d1SAndroid Build Coastguard Worker const uint32_t seqno = (uint32_t)fence_id;
80*bbecb9d1SAndroid Build Coastguard Worker render_context_update_timeline(ctx, ring_idx, seqno);
81*bbecb9d1SAndroid Build Coastguard Worker }
82*bbecb9d1SAndroid Build Coastguard Worker
83*bbecb9d1SAndroid Build Coastguard Worker static const struct virgl_renderer_callbacks render_virgl_cbs = {
84*bbecb9d1SAndroid Build Coastguard Worker .version = VIRGL_RENDERER_CALLBACKS_VERSION,
85*bbecb9d1SAndroid Build Coastguard Worker .write_context_fence = render_virgl_cb_write_context_fence,
86*bbecb9d1SAndroid Build Coastguard Worker };
87*bbecb9d1SAndroid Build Coastguard Worker
88*bbecb9d1SAndroid Build Coastguard Worker void
render_virgl_add_context(struct render_context * ctx)89*bbecb9d1SAndroid Build Coastguard Worker render_virgl_add_context(struct render_context *ctx)
90*bbecb9d1SAndroid Build Coastguard Worker {
91*bbecb9d1SAndroid Build Coastguard Worker struct render_virgl *virgl = render_virgl_lock_struct();
92*bbecb9d1SAndroid Build Coastguard Worker list_addtail(&ctx->head, &virgl->contexts);
93*bbecb9d1SAndroid Build Coastguard Worker render_virgl_unlock_struct();
94*bbecb9d1SAndroid Build Coastguard Worker }
95*bbecb9d1SAndroid Build Coastguard Worker
96*bbecb9d1SAndroid Build Coastguard Worker void
render_virgl_remove_context(struct render_context * ctx)97*bbecb9d1SAndroid Build Coastguard Worker render_virgl_remove_context(struct render_context *ctx)
98*bbecb9d1SAndroid Build Coastguard Worker {
99*bbecb9d1SAndroid Build Coastguard Worker render_virgl_lock_struct();
100*bbecb9d1SAndroid Build Coastguard Worker list_del(&ctx->head);
101*bbecb9d1SAndroid Build Coastguard Worker render_virgl_unlock_struct();
102*bbecb9d1SAndroid Build Coastguard Worker }
103*bbecb9d1SAndroid Build Coastguard Worker
104*bbecb9d1SAndroid Build Coastguard Worker void
render_virgl_fini(void)105*bbecb9d1SAndroid Build Coastguard Worker render_virgl_fini(void)
106*bbecb9d1SAndroid Build Coastguard Worker {
107*bbecb9d1SAndroid Build Coastguard Worker struct render_virgl *virgl = render_virgl_lock_struct();
108*bbecb9d1SAndroid Build Coastguard Worker
109*bbecb9d1SAndroid Build Coastguard Worker if (virgl->init_count) {
110*bbecb9d1SAndroid Build Coastguard Worker virgl->init_count--;
111*bbecb9d1SAndroid Build Coastguard Worker if (!virgl->init_count) {
112*bbecb9d1SAndroid Build Coastguard Worker render_virgl_lock_dispatch();
113*bbecb9d1SAndroid Build Coastguard Worker virgl_renderer_cleanup(virgl);
114*bbecb9d1SAndroid Build Coastguard Worker render_virgl_unlock_dispatch();
115*bbecb9d1SAndroid Build Coastguard Worker }
116*bbecb9d1SAndroid Build Coastguard Worker }
117*bbecb9d1SAndroid Build Coastguard Worker
118*bbecb9d1SAndroid Build Coastguard Worker render_virgl_unlock_struct();
119*bbecb9d1SAndroid Build Coastguard Worker }
120*bbecb9d1SAndroid Build Coastguard Worker
121*bbecb9d1SAndroid Build Coastguard Worker bool
render_virgl_init(uint32_t init_flags)122*bbecb9d1SAndroid Build Coastguard Worker render_virgl_init(uint32_t init_flags)
123*bbecb9d1SAndroid Build Coastguard Worker {
124*bbecb9d1SAndroid Build Coastguard Worker /* we only care if virgl and/or venus are enabled */
125*bbecb9d1SAndroid Build Coastguard Worker init_flags &= VIRGL_RENDERER_VENUS | VIRGL_RENDERER_NO_VIRGL;
126*bbecb9d1SAndroid Build Coastguard Worker
127*bbecb9d1SAndroid Build Coastguard Worker /* always use sync thread and async fence cb for low latency */
128*bbecb9d1SAndroid Build Coastguard Worker init_flags |= VIRGL_RENDERER_THREAD_SYNC | VIRGL_RENDERER_ASYNC_FENCE_CB |
129*bbecb9d1SAndroid Build Coastguard Worker VIRGL_RENDERER_USE_EXTERNAL_BLOB;
130*bbecb9d1SAndroid Build Coastguard Worker
131*bbecb9d1SAndroid Build Coastguard Worker struct render_virgl *virgl = render_virgl_lock_struct();
132*bbecb9d1SAndroid Build Coastguard Worker
133*bbecb9d1SAndroid Build Coastguard Worker if (virgl->init_count) {
134*bbecb9d1SAndroid Build Coastguard Worker if (virgl->init_flags != init_flags) {
135*bbecb9d1SAndroid Build Coastguard Worker render_log("failed to re-initialize with flags 0x%x", init_flags);
136*bbecb9d1SAndroid Build Coastguard Worker goto fail;
137*bbecb9d1SAndroid Build Coastguard Worker }
138*bbecb9d1SAndroid Build Coastguard Worker } else {
139*bbecb9d1SAndroid Build Coastguard Worker render_virgl_lock_dispatch();
140*bbecb9d1SAndroid Build Coastguard Worker virgl_set_debug_callback(render_virgl_debug_callback);
141*bbecb9d1SAndroid Build Coastguard Worker int ret = virgl_renderer_init(virgl, init_flags,
142*bbecb9d1SAndroid Build Coastguard Worker (struct virgl_renderer_callbacks *)&render_virgl_cbs);
143*bbecb9d1SAndroid Build Coastguard Worker render_virgl_unlock_dispatch();
144*bbecb9d1SAndroid Build Coastguard Worker if (ret) {
145*bbecb9d1SAndroid Build Coastguard Worker render_log("failed to initialize virglrenderer");
146*bbecb9d1SAndroid Build Coastguard Worker goto fail;
147*bbecb9d1SAndroid Build Coastguard Worker }
148*bbecb9d1SAndroid Build Coastguard Worker
149*bbecb9d1SAndroid Build Coastguard Worker list_inithead(&virgl->contexts);
150*bbecb9d1SAndroid Build Coastguard Worker virgl->init_flags = init_flags;
151*bbecb9d1SAndroid Build Coastguard Worker }
152*bbecb9d1SAndroid Build Coastguard Worker
153*bbecb9d1SAndroid Build Coastguard Worker virgl->init_count++;
154*bbecb9d1SAndroid Build Coastguard Worker
155*bbecb9d1SAndroid Build Coastguard Worker render_virgl_unlock_struct();
156*bbecb9d1SAndroid Build Coastguard Worker
157*bbecb9d1SAndroid Build Coastguard Worker return true;
158*bbecb9d1SAndroid Build Coastguard Worker
159*bbecb9d1SAndroid Build Coastguard Worker fail:
160*bbecb9d1SAndroid Build Coastguard Worker render_virgl_unlock_struct();
161*bbecb9d1SAndroid Build Coastguard Worker return false;
162*bbecb9d1SAndroid Build Coastguard Worker }
163