xref: /aosp_15_r20/external/virglrenderer/src/virglrenderer.c (revision bbecb9d118dfdb95f99bd754f8fa9be01f189df3)
1*bbecb9d1SAndroid Build Coastguard Worker /**************************************************************************
2*bbecb9d1SAndroid Build Coastguard Worker  *
3*bbecb9d1SAndroid Build Coastguard Worker  * Copyright (C) 2014 Red Hat Inc.
4*bbecb9d1SAndroid Build Coastguard Worker  *
5*bbecb9d1SAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a
6*bbecb9d1SAndroid Build Coastguard Worker  * copy of this software and associated documentation files (the "Software"),
7*bbecb9d1SAndroid Build Coastguard Worker  * to deal in the Software without restriction, including without limitation
8*bbecb9d1SAndroid Build Coastguard Worker  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9*bbecb9d1SAndroid Build Coastguard Worker  * and/or sell copies of the Software, and to permit persons to whom the
10*bbecb9d1SAndroid Build Coastguard Worker  * Software is furnished to do so, subject to the following conditions:
11*bbecb9d1SAndroid Build Coastguard Worker  *
12*bbecb9d1SAndroid Build Coastguard Worker  * The above copyright notice and this permission notice shall be included
13*bbecb9d1SAndroid Build Coastguard Worker  * in all copies or substantial portions of the Software.
14*bbecb9d1SAndroid Build Coastguard Worker  *
15*bbecb9d1SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16*bbecb9d1SAndroid Build Coastguard Worker  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*bbecb9d1SAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18*bbecb9d1SAndroid Build Coastguard Worker  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
19*bbecb9d1SAndroid Build Coastguard Worker  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20*bbecb9d1SAndroid Build Coastguard Worker  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21*bbecb9d1SAndroid Build Coastguard Worker  * OTHER DEALINGS IN THE SOFTWARE.
22*bbecb9d1SAndroid Build Coastguard Worker  *
23*bbecb9d1SAndroid Build Coastguard Worker  **************************************************************************/
24*bbecb9d1SAndroid Build Coastguard Worker 
25*bbecb9d1SAndroid Build Coastguard Worker #include <stdio.h>
26*bbecb9d1SAndroid Build Coastguard Worker #include <time.h>
27*bbecb9d1SAndroid Build Coastguard Worker 
28*bbecb9d1SAndroid Build Coastguard Worker #include <epoxy/gl.h>
29*bbecb9d1SAndroid Build Coastguard Worker 
30*bbecb9d1SAndroid Build Coastguard Worker #include <sys/stat.h>
31*bbecb9d1SAndroid Build Coastguard Worker #include <fcntl.h>
32*bbecb9d1SAndroid Build Coastguard Worker #include <errno.h>
33*bbecb9d1SAndroid Build Coastguard Worker #include <unistd.h>
34*bbecb9d1SAndroid Build Coastguard Worker #include <sys/mman.h>
35*bbecb9d1SAndroid Build Coastguard Worker 
36*bbecb9d1SAndroid Build Coastguard Worker #include "pipe/p_state.h"
37*bbecb9d1SAndroid Build Coastguard Worker #include "util/u_format.h"
38*bbecb9d1SAndroid Build Coastguard Worker #include "util/u_math.h"
39*bbecb9d1SAndroid Build Coastguard Worker #include "vkr_allocator.h"
40*bbecb9d1SAndroid Build Coastguard Worker #include "vkr_renderer.h"
41*bbecb9d1SAndroid Build Coastguard Worker #include "drm_renderer.h"
42*bbecb9d1SAndroid Build Coastguard Worker #include "vrend_renderer.h"
43*bbecb9d1SAndroid Build Coastguard Worker #include "proxy/proxy_renderer.h"
44*bbecb9d1SAndroid Build Coastguard Worker #include "vrend_winsys.h"
45*bbecb9d1SAndroid Build Coastguard Worker 
46*bbecb9d1SAndroid Build Coastguard Worker #include "virglrenderer.h"
47*bbecb9d1SAndroid Build Coastguard Worker #include "virglrenderer_hw.h"
48*bbecb9d1SAndroid Build Coastguard Worker 
49*bbecb9d1SAndroid Build Coastguard Worker #include "virgl_context.h"
50*bbecb9d1SAndroid Build Coastguard Worker #include "virgl_resource.h"
51*bbecb9d1SAndroid Build Coastguard Worker #include "virgl_util.h"
52*bbecb9d1SAndroid Build Coastguard Worker 
53*bbecb9d1SAndroid Build Coastguard Worker struct global_state {
54*bbecb9d1SAndroid Build Coastguard Worker    bool client_initialized;
55*bbecb9d1SAndroid Build Coastguard Worker    void *cookie;
56*bbecb9d1SAndroid Build Coastguard Worker    int flags;
57*bbecb9d1SAndroid Build Coastguard Worker    const struct virgl_renderer_callbacks *cbs;
58*bbecb9d1SAndroid Build Coastguard Worker 
59*bbecb9d1SAndroid Build Coastguard Worker    bool resource_initialized;
60*bbecb9d1SAndroid Build Coastguard Worker    bool context_initialized;
61*bbecb9d1SAndroid Build Coastguard Worker    bool winsys_initialized;
62*bbecb9d1SAndroid Build Coastguard Worker    bool vrend_initialized;
63*bbecb9d1SAndroid Build Coastguard Worker    bool vkr_initialized;
64*bbecb9d1SAndroid Build Coastguard Worker    bool proxy_initialized;
65*bbecb9d1SAndroid Build Coastguard Worker    bool external_winsys_initialized;
66*bbecb9d1SAndroid Build Coastguard Worker };
67*bbecb9d1SAndroid Build Coastguard Worker 
68*bbecb9d1SAndroid Build Coastguard Worker static struct global_state state;
69*bbecb9d1SAndroid Build Coastguard Worker 
70*bbecb9d1SAndroid Build Coastguard Worker /* new API - just wrap internal API for now */
71*bbecb9d1SAndroid Build Coastguard Worker 
virgl_renderer_resource_create_internal(struct virgl_renderer_resource_create_args * args,UNUSED struct iovec * iov,UNUSED uint32_t num_iovs,void * image)72*bbecb9d1SAndroid Build Coastguard Worker static int virgl_renderer_resource_create_internal(struct virgl_renderer_resource_create_args *args,
73*bbecb9d1SAndroid Build Coastguard Worker                                                    UNUSED struct iovec *iov, UNUSED uint32_t num_iovs,
74*bbecb9d1SAndroid Build Coastguard Worker                                                    void *image)
75*bbecb9d1SAndroid Build Coastguard Worker {
76*bbecb9d1SAndroid Build Coastguard Worker    struct virgl_resource *res;
77*bbecb9d1SAndroid Build Coastguard Worker    struct pipe_resource *pipe_res;
78*bbecb9d1SAndroid Build Coastguard Worker    struct vrend_renderer_resource_create_args vrend_args =  { 0 };
79*bbecb9d1SAndroid Build Coastguard Worker 
80*bbecb9d1SAndroid Build Coastguard Worker    if (!state.vrend_initialized)
81*bbecb9d1SAndroid Build Coastguard Worker       return EINVAL;
82*bbecb9d1SAndroid Build Coastguard Worker 
83*bbecb9d1SAndroid Build Coastguard Worker    /* do not accept handle 0 */
84*bbecb9d1SAndroid Build Coastguard Worker    if (args->handle == 0)
85*bbecb9d1SAndroid Build Coastguard Worker       return EINVAL;
86*bbecb9d1SAndroid Build Coastguard Worker 
87*bbecb9d1SAndroid Build Coastguard Worker    vrend_args.target = args->target;
88*bbecb9d1SAndroid Build Coastguard Worker    vrend_args.format = args->format;
89*bbecb9d1SAndroid Build Coastguard Worker    vrend_args.bind = args->bind;
90*bbecb9d1SAndroid Build Coastguard Worker    vrend_args.width = args->width;
91*bbecb9d1SAndroid Build Coastguard Worker    vrend_args.height = args->height;
92*bbecb9d1SAndroid Build Coastguard Worker    vrend_args.depth = args->depth;
93*bbecb9d1SAndroid Build Coastguard Worker    vrend_args.array_size = args->array_size;
94*bbecb9d1SAndroid Build Coastguard Worker    vrend_args.nr_samples = args->nr_samples;
95*bbecb9d1SAndroid Build Coastguard Worker    vrend_args.last_level = args->last_level;
96*bbecb9d1SAndroid Build Coastguard Worker    vrend_args.flags = args->flags;
97*bbecb9d1SAndroid Build Coastguard Worker 
98*bbecb9d1SAndroid Build Coastguard Worker    pipe_res = vrend_renderer_resource_create(&vrend_args, image);
99*bbecb9d1SAndroid Build Coastguard Worker    if (!pipe_res)
100*bbecb9d1SAndroid Build Coastguard Worker       return EINVAL;
101*bbecb9d1SAndroid Build Coastguard Worker 
102*bbecb9d1SAndroid Build Coastguard Worker    res = virgl_resource_create_from_pipe(args->handle, pipe_res, iov, num_iovs);
103*bbecb9d1SAndroid Build Coastguard Worker    if (!res) {
104*bbecb9d1SAndroid Build Coastguard Worker       vrend_renderer_resource_destroy((struct vrend_resource *)pipe_res);
105*bbecb9d1SAndroid Build Coastguard Worker       return -ENOMEM;
106*bbecb9d1SAndroid Build Coastguard Worker    }
107*bbecb9d1SAndroid Build Coastguard Worker 
108*bbecb9d1SAndroid Build Coastguard Worker    res->map_info = vrend_renderer_resource_get_map_info(pipe_res);
109*bbecb9d1SAndroid Build Coastguard Worker 
110*bbecb9d1SAndroid Build Coastguard Worker    return 0;
111*bbecb9d1SAndroid Build Coastguard Worker }
112*bbecb9d1SAndroid Build Coastguard Worker 
virgl_renderer_resource_create(struct virgl_renderer_resource_create_args * args,struct iovec * iov,uint32_t num_iovs)113*bbecb9d1SAndroid Build Coastguard Worker int virgl_renderer_resource_create(struct virgl_renderer_resource_create_args *args,
114*bbecb9d1SAndroid Build Coastguard Worker                                    struct iovec *iov, uint32_t num_iovs)
115*bbecb9d1SAndroid Build Coastguard Worker {
116*bbecb9d1SAndroid Build Coastguard Worker    TRACE_FUNC();
117*bbecb9d1SAndroid Build Coastguard Worker    return virgl_renderer_resource_create_internal(args, iov, num_iovs, NULL);
118*bbecb9d1SAndroid Build Coastguard Worker }
119*bbecb9d1SAndroid Build Coastguard Worker 
virgl_renderer_resource_import_eglimage(struct virgl_renderer_resource_create_args * args,void * image)120*bbecb9d1SAndroid Build Coastguard Worker int virgl_renderer_resource_import_eglimage(struct virgl_renderer_resource_create_args *args, void *image)
121*bbecb9d1SAndroid Build Coastguard Worker {
122*bbecb9d1SAndroid Build Coastguard Worker    TRACE_FUNC();
123*bbecb9d1SAndroid Build Coastguard Worker    return virgl_renderer_resource_create_internal(args, NULL, 0, image);
124*bbecb9d1SAndroid Build Coastguard Worker }
125*bbecb9d1SAndroid Build Coastguard Worker 
virgl_renderer_resource_set_priv(uint32_t res_handle,void * priv)126*bbecb9d1SAndroid Build Coastguard Worker void virgl_renderer_resource_set_priv(uint32_t res_handle, void *priv)
127*bbecb9d1SAndroid Build Coastguard Worker {
128*bbecb9d1SAndroid Build Coastguard Worker    struct virgl_resource *res = virgl_resource_lookup(res_handle);
129*bbecb9d1SAndroid Build Coastguard Worker    if (!res)
130*bbecb9d1SAndroid Build Coastguard Worker       return;
131*bbecb9d1SAndroid Build Coastguard Worker 
132*bbecb9d1SAndroid Build Coastguard Worker    res->private_data = priv;
133*bbecb9d1SAndroid Build Coastguard Worker }
134*bbecb9d1SAndroid Build Coastguard Worker 
virgl_renderer_resource_get_priv(uint32_t res_handle)135*bbecb9d1SAndroid Build Coastguard Worker void *virgl_renderer_resource_get_priv(uint32_t res_handle)
136*bbecb9d1SAndroid Build Coastguard Worker {
137*bbecb9d1SAndroid Build Coastguard Worker    struct virgl_resource *res = virgl_resource_lookup(res_handle);
138*bbecb9d1SAndroid Build Coastguard Worker    if (!res)
139*bbecb9d1SAndroid Build Coastguard Worker       return NULL;
140*bbecb9d1SAndroid Build Coastguard Worker 
141*bbecb9d1SAndroid Build Coastguard Worker    return res->private_data;
142*bbecb9d1SAndroid Build Coastguard Worker }
143*bbecb9d1SAndroid Build Coastguard Worker 
detach_resource(struct virgl_context * ctx,void * data)144*bbecb9d1SAndroid Build Coastguard Worker static bool detach_resource(struct virgl_context *ctx, void *data)
145*bbecb9d1SAndroid Build Coastguard Worker {
146*bbecb9d1SAndroid Build Coastguard Worker    struct virgl_resource *res = data;
147*bbecb9d1SAndroid Build Coastguard Worker    ctx->detach_resource(ctx, res);
148*bbecb9d1SAndroid Build Coastguard Worker    return true;
149*bbecb9d1SAndroid Build Coastguard Worker }
150*bbecb9d1SAndroid Build Coastguard Worker 
virgl_renderer_resource_unref(uint32_t res_handle)151*bbecb9d1SAndroid Build Coastguard Worker void virgl_renderer_resource_unref(uint32_t res_handle)
152*bbecb9d1SAndroid Build Coastguard Worker {
153*bbecb9d1SAndroid Build Coastguard Worker    struct virgl_resource *res = virgl_resource_lookup(res_handle);
154*bbecb9d1SAndroid Build Coastguard Worker    struct virgl_context_foreach_args args;
155*bbecb9d1SAndroid Build Coastguard Worker 
156*bbecb9d1SAndroid Build Coastguard Worker    if (!res)
157*bbecb9d1SAndroid Build Coastguard Worker       return;
158*bbecb9d1SAndroid Build Coastguard Worker 
159*bbecb9d1SAndroid Build Coastguard Worker    args.callback = detach_resource;
160*bbecb9d1SAndroid Build Coastguard Worker    args.data = res;
161*bbecb9d1SAndroid Build Coastguard Worker    virgl_context_foreach(&args);
162*bbecb9d1SAndroid Build Coastguard Worker 
163*bbecb9d1SAndroid Build Coastguard Worker    virgl_resource_remove(res->res_id);
164*bbecb9d1SAndroid Build Coastguard Worker }
165*bbecb9d1SAndroid Build Coastguard Worker 
virgl_renderer_fill_caps(uint32_t set,uint32_t version,void * caps)166*bbecb9d1SAndroid Build Coastguard Worker void virgl_renderer_fill_caps(uint32_t set, uint32_t version,
167*bbecb9d1SAndroid Build Coastguard Worker                               void *caps)
168*bbecb9d1SAndroid Build Coastguard Worker {
169*bbecb9d1SAndroid Build Coastguard Worker    switch (set) {
170*bbecb9d1SAndroid Build Coastguard Worker    case VIRGL_RENDERER_CAPSET_VIRGL:
171*bbecb9d1SAndroid Build Coastguard Worker    case VIRGL_RENDERER_CAPSET_VIRGL2:
172*bbecb9d1SAndroid Build Coastguard Worker       if (state.vrend_initialized)
173*bbecb9d1SAndroid Build Coastguard Worker          vrend_renderer_fill_caps(set, version, (union virgl_caps *)caps);
174*bbecb9d1SAndroid Build Coastguard Worker       break;
175*bbecb9d1SAndroid Build Coastguard Worker    case VIRGL_RENDERER_CAPSET_VENUS:
176*bbecb9d1SAndroid Build Coastguard Worker       if (state.vkr_initialized)
177*bbecb9d1SAndroid Build Coastguard Worker          vkr_get_capset(caps);
178*bbecb9d1SAndroid Build Coastguard Worker       break;
179*bbecb9d1SAndroid Build Coastguard Worker    case VIRGL_RENDERER_CAPSET_DRM:
180*bbecb9d1SAndroid Build Coastguard Worker       drm_renderer_capset(caps);
181*bbecb9d1SAndroid Build Coastguard Worker       break;
182*bbecb9d1SAndroid Build Coastguard Worker    default:
183*bbecb9d1SAndroid Build Coastguard Worker       break;
184*bbecb9d1SAndroid Build Coastguard Worker    }
185*bbecb9d1SAndroid Build Coastguard Worker }
186*bbecb9d1SAndroid Build Coastguard Worker 
per_context_fence_retire(struct virgl_context * ctx,uint32_t ring_idx,uint64_t fence_id)187*bbecb9d1SAndroid Build Coastguard Worker static void per_context_fence_retire(struct virgl_context *ctx,
188*bbecb9d1SAndroid Build Coastguard Worker                                      uint32_t ring_idx,
189*bbecb9d1SAndroid Build Coastguard Worker                                      uint64_t fence_id)
190*bbecb9d1SAndroid Build Coastguard Worker {
191*bbecb9d1SAndroid Build Coastguard Worker    state.cbs->write_context_fence(state.cookie,
192*bbecb9d1SAndroid Build Coastguard Worker                                   ctx->ctx_id,
193*bbecb9d1SAndroid Build Coastguard Worker                                   ring_idx,
194*bbecb9d1SAndroid Build Coastguard Worker                                   fence_id);
195*bbecb9d1SAndroid Build Coastguard Worker }
196*bbecb9d1SAndroid Build Coastguard Worker 
virgl_renderer_context_create_with_flags(uint32_t ctx_id,uint32_t ctx_flags,uint32_t nlen,const char * name)197*bbecb9d1SAndroid Build Coastguard Worker int virgl_renderer_context_create_with_flags(uint32_t ctx_id,
198*bbecb9d1SAndroid Build Coastguard Worker                                              uint32_t ctx_flags,
199*bbecb9d1SAndroid Build Coastguard Worker                                              uint32_t nlen,
200*bbecb9d1SAndroid Build Coastguard Worker                                              const char *name)
201*bbecb9d1SAndroid Build Coastguard Worker {
202*bbecb9d1SAndroid Build Coastguard Worker    const enum virgl_renderer_capset capset_id =
203*bbecb9d1SAndroid Build Coastguard Worker       ctx_flags & VIRGL_RENDERER_CONTEXT_FLAG_CAPSET_ID_MASK;
204*bbecb9d1SAndroid Build Coastguard Worker    struct virgl_context *ctx;
205*bbecb9d1SAndroid Build Coastguard Worker    int ret;
206*bbecb9d1SAndroid Build Coastguard Worker 
207*bbecb9d1SAndroid Build Coastguard Worker    TRACE_FUNC();
208*bbecb9d1SAndroid Build Coastguard Worker 
209*bbecb9d1SAndroid Build Coastguard Worker    /* user context id must be greater than 0 */
210*bbecb9d1SAndroid Build Coastguard Worker    if (ctx_id == 0)
211*bbecb9d1SAndroid Build Coastguard Worker       return EINVAL;
212*bbecb9d1SAndroid Build Coastguard Worker 
213*bbecb9d1SAndroid Build Coastguard Worker    /* unsupported flags */
214*bbecb9d1SAndroid Build Coastguard Worker    if (ctx_flags & ~VIRGL_RENDERER_CONTEXT_FLAG_CAPSET_ID_MASK)
215*bbecb9d1SAndroid Build Coastguard Worker       return EINVAL;
216*bbecb9d1SAndroid Build Coastguard Worker 
217*bbecb9d1SAndroid Build Coastguard Worker    ctx = virgl_context_lookup(ctx_id);
218*bbecb9d1SAndroid Build Coastguard Worker    if (ctx) {
219*bbecb9d1SAndroid Build Coastguard Worker       return ctx->capset_id == capset_id ? 0 : EINVAL;
220*bbecb9d1SAndroid Build Coastguard Worker    }
221*bbecb9d1SAndroid Build Coastguard Worker 
222*bbecb9d1SAndroid Build Coastguard Worker    switch (capset_id) {
223*bbecb9d1SAndroid Build Coastguard Worker    case VIRGL_RENDERER_CAPSET_VIRGL:
224*bbecb9d1SAndroid Build Coastguard Worker    case VIRGL_RENDERER_CAPSET_VIRGL2:
225*bbecb9d1SAndroid Build Coastguard Worker       if (!state.vrend_initialized)
226*bbecb9d1SAndroid Build Coastguard Worker          return EINVAL;
227*bbecb9d1SAndroid Build Coastguard Worker       ctx = vrend_renderer_context_create(ctx_id, nlen, name);
228*bbecb9d1SAndroid Build Coastguard Worker       break;
229*bbecb9d1SAndroid Build Coastguard Worker    case VIRGL_RENDERER_CAPSET_VENUS:
230*bbecb9d1SAndroid Build Coastguard Worker       if (state.proxy_initialized)
231*bbecb9d1SAndroid Build Coastguard Worker          ctx = proxy_context_create(ctx_id, ctx_flags, nlen, name);
232*bbecb9d1SAndroid Build Coastguard Worker       else if (state.vkr_initialized)
233*bbecb9d1SAndroid Build Coastguard Worker          ctx = vkr_context_create(nlen, name);
234*bbecb9d1SAndroid Build Coastguard Worker       else
235*bbecb9d1SAndroid Build Coastguard Worker          return EINVAL;
236*bbecb9d1SAndroid Build Coastguard Worker       break;
237*bbecb9d1SAndroid Build Coastguard Worker    case VIRGL_RENDERER_CAPSET_DRM:
238*bbecb9d1SAndroid Build Coastguard Worker       ctx = drm_renderer_create(nlen, name);
239*bbecb9d1SAndroid Build Coastguard Worker       break;
240*bbecb9d1SAndroid Build Coastguard Worker    default:
241*bbecb9d1SAndroid Build Coastguard Worker       return EINVAL;
242*bbecb9d1SAndroid Build Coastguard Worker       break;
243*bbecb9d1SAndroid Build Coastguard Worker    }
244*bbecb9d1SAndroid Build Coastguard Worker    if (!ctx)
245*bbecb9d1SAndroid Build Coastguard Worker       return ENOMEM;
246*bbecb9d1SAndroid Build Coastguard Worker 
247*bbecb9d1SAndroid Build Coastguard Worker    ctx->ctx_id = ctx_id;
248*bbecb9d1SAndroid Build Coastguard Worker    ctx->capset_id = capset_id;
249*bbecb9d1SAndroid Build Coastguard Worker    ctx->fence_retire = per_context_fence_retire;
250*bbecb9d1SAndroid Build Coastguard Worker 
251*bbecb9d1SAndroid Build Coastguard Worker    ret = virgl_context_add(ctx);
252*bbecb9d1SAndroid Build Coastguard Worker    if (ret) {
253*bbecb9d1SAndroid Build Coastguard Worker       ctx->destroy(ctx);
254*bbecb9d1SAndroid Build Coastguard Worker       return ret;
255*bbecb9d1SAndroid Build Coastguard Worker    }
256*bbecb9d1SAndroid Build Coastguard Worker 
257*bbecb9d1SAndroid Build Coastguard Worker    return 0;
258*bbecb9d1SAndroid Build Coastguard Worker }
259*bbecb9d1SAndroid Build Coastguard Worker 
virgl_renderer_context_create(uint32_t handle,uint32_t nlen,const char * name)260*bbecb9d1SAndroid Build Coastguard Worker int virgl_renderer_context_create(uint32_t handle, uint32_t nlen, const char *name)
261*bbecb9d1SAndroid Build Coastguard Worker {
262*bbecb9d1SAndroid Build Coastguard Worker    return virgl_renderer_context_create_with_flags(handle,
263*bbecb9d1SAndroid Build Coastguard Worker                                                    VIRGL_RENDERER_CAPSET_VIRGL2,
264*bbecb9d1SAndroid Build Coastguard Worker                                                    nlen,
265*bbecb9d1SAndroid Build Coastguard Worker                                                    name);
266*bbecb9d1SAndroid Build Coastguard Worker }
267*bbecb9d1SAndroid Build Coastguard Worker 
virgl_renderer_context_destroy(uint32_t handle)268*bbecb9d1SAndroid Build Coastguard Worker void virgl_renderer_context_destroy(uint32_t handle)
269*bbecb9d1SAndroid Build Coastguard Worker {
270*bbecb9d1SAndroid Build Coastguard Worker    TRACE_FUNC();
271*bbecb9d1SAndroid Build Coastguard Worker    virgl_context_remove(handle);
272*bbecb9d1SAndroid Build Coastguard Worker }
273*bbecb9d1SAndroid Build Coastguard Worker 
virgl_renderer_submit_cmd(void * buffer,int ctx_id,int ndw)274*bbecb9d1SAndroid Build Coastguard Worker int virgl_renderer_submit_cmd(void *buffer,
275*bbecb9d1SAndroid Build Coastguard Worker                               int ctx_id,
276*bbecb9d1SAndroid Build Coastguard Worker                               int ndw)
277*bbecb9d1SAndroid Build Coastguard Worker {
278*bbecb9d1SAndroid Build Coastguard Worker    TRACE_FUNC();
279*bbecb9d1SAndroid Build Coastguard Worker    struct virgl_context *ctx = virgl_context_lookup(ctx_id);
280*bbecb9d1SAndroid Build Coastguard Worker    if (!ctx)
281*bbecb9d1SAndroid Build Coastguard Worker       return EINVAL;
282*bbecb9d1SAndroid Build Coastguard Worker 
283*bbecb9d1SAndroid Build Coastguard Worker    if (ndw < 0 || (unsigned)ndw > UINT32_MAX / sizeof(uint32_t))
284*bbecb9d1SAndroid Build Coastguard Worker       return EINVAL;
285*bbecb9d1SAndroid Build Coastguard Worker 
286*bbecb9d1SAndroid Build Coastguard Worker    return ctx->submit_cmd(ctx, buffer, ndw * sizeof(uint32_t));
287*bbecb9d1SAndroid Build Coastguard Worker }
288*bbecb9d1SAndroid Build Coastguard Worker 
virgl_renderer_transfer_write_iov(uint32_t handle,uint32_t ctx_id,int level,uint32_t stride,uint32_t layer_stride,struct virgl_box * box,uint64_t offset,struct iovec * iovec,unsigned int iovec_cnt)289*bbecb9d1SAndroid Build Coastguard Worker int virgl_renderer_transfer_write_iov(uint32_t handle,
290*bbecb9d1SAndroid Build Coastguard Worker                                       uint32_t ctx_id,
291*bbecb9d1SAndroid Build Coastguard Worker                                       int level,
292*bbecb9d1SAndroid Build Coastguard Worker                                       uint32_t stride,
293*bbecb9d1SAndroid Build Coastguard Worker                                       uint32_t layer_stride,
294*bbecb9d1SAndroid Build Coastguard Worker                                       struct virgl_box *box,
295*bbecb9d1SAndroid Build Coastguard Worker                                       uint64_t offset,
296*bbecb9d1SAndroid Build Coastguard Worker                                       struct iovec *iovec,
297*bbecb9d1SAndroid Build Coastguard Worker                                       unsigned int iovec_cnt)
298*bbecb9d1SAndroid Build Coastguard Worker {
299*bbecb9d1SAndroid Build Coastguard Worker    TRACE_FUNC();
300*bbecb9d1SAndroid Build Coastguard Worker 
301*bbecb9d1SAndroid Build Coastguard Worker    struct virgl_resource *res = virgl_resource_lookup(handle);
302*bbecb9d1SAndroid Build Coastguard Worker    struct vrend_transfer_info transfer_info;
303*bbecb9d1SAndroid Build Coastguard Worker 
304*bbecb9d1SAndroid Build Coastguard Worker    if (!res)
305*bbecb9d1SAndroid Build Coastguard Worker       return EINVAL;
306*bbecb9d1SAndroid Build Coastguard Worker 
307*bbecb9d1SAndroid Build Coastguard Worker    transfer_info.level = level;
308*bbecb9d1SAndroid Build Coastguard Worker    transfer_info.stride = stride;
309*bbecb9d1SAndroid Build Coastguard Worker    transfer_info.layer_stride = layer_stride;
310*bbecb9d1SAndroid Build Coastguard Worker    transfer_info.box = (struct pipe_box *)box;
311*bbecb9d1SAndroid Build Coastguard Worker    transfer_info.offset = offset;
312*bbecb9d1SAndroid Build Coastguard Worker    transfer_info.iovec = iovec;
313*bbecb9d1SAndroid Build Coastguard Worker    transfer_info.iovec_cnt = iovec_cnt;
314*bbecb9d1SAndroid Build Coastguard Worker    transfer_info.synchronized = false;
315*bbecb9d1SAndroid Build Coastguard Worker 
316*bbecb9d1SAndroid Build Coastguard Worker    if (ctx_id) {
317*bbecb9d1SAndroid Build Coastguard Worker       struct virgl_context *ctx = virgl_context_lookup(ctx_id);
318*bbecb9d1SAndroid Build Coastguard Worker       if (!ctx)
319*bbecb9d1SAndroid Build Coastguard Worker          return EINVAL;
320*bbecb9d1SAndroid Build Coastguard Worker 
321*bbecb9d1SAndroid Build Coastguard Worker       return ctx->transfer_3d(ctx, res, &transfer_info,
322*bbecb9d1SAndroid Build Coastguard Worker                               VIRGL_TRANSFER_TO_HOST);
323*bbecb9d1SAndroid Build Coastguard Worker    } else {
324*bbecb9d1SAndroid Build Coastguard Worker       if (!res->pipe_resource)
325*bbecb9d1SAndroid Build Coastguard Worker          return EINVAL;
326*bbecb9d1SAndroid Build Coastguard Worker 
327*bbecb9d1SAndroid Build Coastguard Worker       return vrend_renderer_transfer_pipe(res->pipe_resource, &transfer_info,
328*bbecb9d1SAndroid Build Coastguard Worker                                           VIRGL_TRANSFER_TO_HOST);
329*bbecb9d1SAndroid Build Coastguard Worker    }
330*bbecb9d1SAndroid Build Coastguard Worker }
331*bbecb9d1SAndroid Build Coastguard Worker 
virgl_renderer_transfer_read_iov(uint32_t handle,uint32_t ctx_id,uint32_t level,uint32_t stride,uint32_t layer_stride,struct virgl_box * box,uint64_t offset,struct iovec * iovec,int iovec_cnt)332*bbecb9d1SAndroid Build Coastguard Worker int virgl_renderer_transfer_read_iov(uint32_t handle, uint32_t ctx_id,
333*bbecb9d1SAndroid Build Coastguard Worker                                      uint32_t level, uint32_t stride,
334*bbecb9d1SAndroid Build Coastguard Worker                                      uint32_t layer_stride,
335*bbecb9d1SAndroid Build Coastguard Worker                                      struct virgl_box *box,
336*bbecb9d1SAndroid Build Coastguard Worker                                      uint64_t offset, struct iovec *iovec,
337*bbecb9d1SAndroid Build Coastguard Worker                                      int iovec_cnt)
338*bbecb9d1SAndroid Build Coastguard Worker {
339*bbecb9d1SAndroid Build Coastguard Worker    TRACE_FUNC();
340*bbecb9d1SAndroid Build Coastguard Worker    struct virgl_resource *res = virgl_resource_lookup(handle);
341*bbecb9d1SAndroid Build Coastguard Worker    struct vrend_transfer_info transfer_info;
342*bbecb9d1SAndroid Build Coastguard Worker 
343*bbecb9d1SAndroid Build Coastguard Worker    if (!res)
344*bbecb9d1SAndroid Build Coastguard Worker       return EINVAL;
345*bbecb9d1SAndroid Build Coastguard Worker 
346*bbecb9d1SAndroid Build Coastguard Worker    transfer_info.level = level;
347*bbecb9d1SAndroid Build Coastguard Worker    transfer_info.stride = stride;
348*bbecb9d1SAndroid Build Coastguard Worker    transfer_info.layer_stride = layer_stride;
349*bbecb9d1SAndroid Build Coastguard Worker    transfer_info.box = (struct pipe_box *)box;
350*bbecb9d1SAndroid Build Coastguard Worker    transfer_info.offset = offset;
351*bbecb9d1SAndroid Build Coastguard Worker    transfer_info.iovec = iovec;
352*bbecb9d1SAndroid Build Coastguard Worker    transfer_info.iovec_cnt = iovec_cnt;
353*bbecb9d1SAndroid Build Coastguard Worker    transfer_info.synchronized = false;
354*bbecb9d1SAndroid Build Coastguard Worker 
355*bbecb9d1SAndroid Build Coastguard Worker    if (ctx_id) {
356*bbecb9d1SAndroid Build Coastguard Worker       struct virgl_context *ctx = virgl_context_lookup(ctx_id);
357*bbecb9d1SAndroid Build Coastguard Worker       if (!ctx)
358*bbecb9d1SAndroid Build Coastguard Worker          return EINVAL;
359*bbecb9d1SAndroid Build Coastguard Worker 
360*bbecb9d1SAndroid Build Coastguard Worker       return ctx->transfer_3d(ctx, res, &transfer_info,
361*bbecb9d1SAndroid Build Coastguard Worker                               VIRGL_TRANSFER_FROM_HOST);
362*bbecb9d1SAndroid Build Coastguard Worker    } else {
363*bbecb9d1SAndroid Build Coastguard Worker       if (!res->pipe_resource)
364*bbecb9d1SAndroid Build Coastguard Worker          return EINVAL;
365*bbecb9d1SAndroid Build Coastguard Worker 
366*bbecb9d1SAndroid Build Coastguard Worker       return vrend_renderer_transfer_pipe(res->pipe_resource, &transfer_info,
367*bbecb9d1SAndroid Build Coastguard Worker                                           VIRGL_TRANSFER_FROM_HOST);
368*bbecb9d1SAndroid Build Coastguard Worker    }
369*bbecb9d1SAndroid Build Coastguard Worker }
370*bbecb9d1SAndroid Build Coastguard Worker 
virgl_renderer_resource_attach_iov(int res_handle,struct iovec * iov,int num_iovs)371*bbecb9d1SAndroid Build Coastguard Worker int virgl_renderer_resource_attach_iov(int res_handle, struct iovec *iov,
372*bbecb9d1SAndroid Build Coastguard Worker                                        int num_iovs)
373*bbecb9d1SAndroid Build Coastguard Worker {
374*bbecb9d1SAndroid Build Coastguard Worker    TRACE_FUNC();
375*bbecb9d1SAndroid Build Coastguard Worker    struct virgl_resource *res = virgl_resource_lookup(res_handle);
376*bbecb9d1SAndroid Build Coastguard Worker    if (!res)
377*bbecb9d1SAndroid Build Coastguard Worker       return EINVAL;
378*bbecb9d1SAndroid Build Coastguard Worker 
379*bbecb9d1SAndroid Build Coastguard Worker    return virgl_resource_attach_iov(res, iov, num_iovs);
380*bbecb9d1SAndroid Build Coastguard Worker }
381*bbecb9d1SAndroid Build Coastguard Worker 
virgl_renderer_resource_detach_iov(int res_handle,struct iovec ** iov_p,int * num_iovs_p)382*bbecb9d1SAndroid Build Coastguard Worker void virgl_renderer_resource_detach_iov(int res_handle, struct iovec **iov_p, int *num_iovs_p)
383*bbecb9d1SAndroid Build Coastguard Worker {
384*bbecb9d1SAndroid Build Coastguard Worker    TRACE_FUNC();
385*bbecb9d1SAndroid Build Coastguard Worker    struct virgl_resource *res = virgl_resource_lookup(res_handle);
386*bbecb9d1SAndroid Build Coastguard Worker    if (!res)
387*bbecb9d1SAndroid Build Coastguard Worker       return;
388*bbecb9d1SAndroid Build Coastguard Worker 
389*bbecb9d1SAndroid Build Coastguard Worker    if (iov_p)
390*bbecb9d1SAndroid Build Coastguard Worker       *iov_p = (struct iovec *)res->iov;
391*bbecb9d1SAndroid Build Coastguard Worker    if (num_iovs_p)
392*bbecb9d1SAndroid Build Coastguard Worker       *num_iovs_p = res->iov_count;
393*bbecb9d1SAndroid Build Coastguard Worker 
394*bbecb9d1SAndroid Build Coastguard Worker    virgl_resource_detach_iov(res);
395*bbecb9d1SAndroid Build Coastguard Worker }
396*bbecb9d1SAndroid Build Coastguard Worker 
virgl_renderer_create_fence(int client_fence_id,UNUSED uint32_t ctx_id)397*bbecb9d1SAndroid Build Coastguard Worker int virgl_renderer_create_fence(int client_fence_id, UNUSED uint32_t ctx_id)
398*bbecb9d1SAndroid Build Coastguard Worker {
399*bbecb9d1SAndroid Build Coastguard Worker    TRACE_FUNC();
400*bbecb9d1SAndroid Build Coastguard Worker    const uint32_t fence_id = (uint32_t)client_fence_id;
401*bbecb9d1SAndroid Build Coastguard Worker    if (state.vrend_initialized)
402*bbecb9d1SAndroid Build Coastguard Worker       return vrend_renderer_create_ctx0_fence(fence_id);
403*bbecb9d1SAndroid Build Coastguard Worker    return EINVAL;
404*bbecb9d1SAndroid Build Coastguard Worker }
405*bbecb9d1SAndroid Build Coastguard Worker 
virgl_renderer_context_create_fence(uint32_t ctx_id,uint32_t flags,uint32_t ring_idx,uint64_t fence_id)406*bbecb9d1SAndroid Build Coastguard Worker int virgl_renderer_context_create_fence(uint32_t ctx_id,
407*bbecb9d1SAndroid Build Coastguard Worker                                         uint32_t flags,
408*bbecb9d1SAndroid Build Coastguard Worker                                         uint32_t ring_idx,
409*bbecb9d1SAndroid Build Coastguard Worker                                         uint64_t fence_id)
410*bbecb9d1SAndroid Build Coastguard Worker {
411*bbecb9d1SAndroid Build Coastguard Worker    TRACE_FUNC();
412*bbecb9d1SAndroid Build Coastguard Worker    struct virgl_context *ctx = virgl_context_lookup(ctx_id);
413*bbecb9d1SAndroid Build Coastguard Worker    if (!ctx)
414*bbecb9d1SAndroid Build Coastguard Worker       return -EINVAL;
415*bbecb9d1SAndroid Build Coastguard Worker 
416*bbecb9d1SAndroid Build Coastguard Worker    assert(state.cbs->version >= 3 && state.cbs->write_context_fence);
417*bbecb9d1SAndroid Build Coastguard Worker    return ctx->submit_fence(ctx, flags, ring_idx, fence_id);
418*bbecb9d1SAndroid Build Coastguard Worker }
419*bbecb9d1SAndroid Build Coastguard Worker 
virgl_renderer_context_poll(uint32_t ctx_id)420*bbecb9d1SAndroid Build Coastguard Worker void virgl_renderer_context_poll(uint32_t ctx_id)
421*bbecb9d1SAndroid Build Coastguard Worker {
422*bbecb9d1SAndroid Build Coastguard Worker    struct virgl_context *ctx = virgl_context_lookup(ctx_id);
423*bbecb9d1SAndroid Build Coastguard Worker    if (!ctx)
424*bbecb9d1SAndroid Build Coastguard Worker       return;
425*bbecb9d1SAndroid Build Coastguard Worker 
426*bbecb9d1SAndroid Build Coastguard Worker    ctx->retire_fences(ctx);
427*bbecb9d1SAndroid Build Coastguard Worker }
428*bbecb9d1SAndroid Build Coastguard Worker 
virgl_renderer_context_get_poll_fd(uint32_t ctx_id)429*bbecb9d1SAndroid Build Coastguard Worker int virgl_renderer_context_get_poll_fd(uint32_t ctx_id)
430*bbecb9d1SAndroid Build Coastguard Worker {
431*bbecb9d1SAndroid Build Coastguard Worker    struct virgl_context *ctx = virgl_context_lookup(ctx_id);
432*bbecb9d1SAndroid Build Coastguard Worker    if (!ctx)
433*bbecb9d1SAndroid Build Coastguard Worker       return -1;
434*bbecb9d1SAndroid Build Coastguard Worker 
435*bbecb9d1SAndroid Build Coastguard Worker    return ctx->get_fencing_fd(ctx);
436*bbecb9d1SAndroid Build Coastguard Worker }
437*bbecb9d1SAndroid Build Coastguard Worker 
virgl_renderer_force_ctx_0(void)438*bbecb9d1SAndroid Build Coastguard Worker void virgl_renderer_force_ctx_0(void)
439*bbecb9d1SAndroid Build Coastguard Worker {
440*bbecb9d1SAndroid Build Coastguard Worker    if (state.vrend_initialized)
441*bbecb9d1SAndroid Build Coastguard Worker       vrend_renderer_force_ctx_0();
442*bbecb9d1SAndroid Build Coastguard Worker }
443*bbecb9d1SAndroid Build Coastguard Worker 
virgl_renderer_ctx_attach_resource(int ctx_id,int res_handle)444*bbecb9d1SAndroid Build Coastguard Worker void virgl_renderer_ctx_attach_resource(int ctx_id, int res_handle)
445*bbecb9d1SAndroid Build Coastguard Worker {
446*bbecb9d1SAndroid Build Coastguard Worker    TRACE_FUNC();
447*bbecb9d1SAndroid Build Coastguard Worker    struct virgl_context *ctx = virgl_context_lookup(ctx_id);
448*bbecb9d1SAndroid Build Coastguard Worker    struct virgl_resource *res = virgl_resource_lookup(res_handle);
449*bbecb9d1SAndroid Build Coastguard Worker    if (!ctx || !res)
450*bbecb9d1SAndroid Build Coastguard Worker       return;
451*bbecb9d1SAndroid Build Coastguard Worker    ctx->attach_resource(ctx, res);
452*bbecb9d1SAndroid Build Coastguard Worker }
453*bbecb9d1SAndroid Build Coastguard Worker 
virgl_renderer_ctx_detach_resource(int ctx_id,int res_handle)454*bbecb9d1SAndroid Build Coastguard Worker void virgl_renderer_ctx_detach_resource(int ctx_id, int res_handle)
455*bbecb9d1SAndroid Build Coastguard Worker {
456*bbecb9d1SAndroid Build Coastguard Worker    TRACE_FUNC();
457*bbecb9d1SAndroid Build Coastguard Worker    struct virgl_context *ctx = virgl_context_lookup(ctx_id);
458*bbecb9d1SAndroid Build Coastguard Worker    struct virgl_resource *res = virgl_resource_lookup(res_handle);
459*bbecb9d1SAndroid Build Coastguard Worker    if (!ctx || !res)
460*bbecb9d1SAndroid Build Coastguard Worker       return;
461*bbecb9d1SAndroid Build Coastguard Worker    ctx->detach_resource(ctx, res);
462*bbecb9d1SAndroid Build Coastguard Worker }
463*bbecb9d1SAndroid Build Coastguard Worker 
virgl_renderer_resource_get_info(int res_handle,struct virgl_renderer_resource_info * info)464*bbecb9d1SAndroid Build Coastguard Worker int virgl_renderer_resource_get_info(int res_handle,
465*bbecb9d1SAndroid Build Coastguard Worker                                      struct virgl_renderer_resource_info *info)
466*bbecb9d1SAndroid Build Coastguard Worker {
467*bbecb9d1SAndroid Build Coastguard Worker    TRACE_FUNC();
468*bbecb9d1SAndroid Build Coastguard Worker    struct virgl_resource *res = virgl_resource_lookup(res_handle);
469*bbecb9d1SAndroid Build Coastguard Worker 
470*bbecb9d1SAndroid Build Coastguard Worker    if (!res || !res->pipe_resource)
471*bbecb9d1SAndroid Build Coastguard Worker       return EINVAL;
472*bbecb9d1SAndroid Build Coastguard Worker    if (!info)
473*bbecb9d1SAndroid Build Coastguard Worker       return EINVAL;
474*bbecb9d1SAndroid Build Coastguard Worker 
475*bbecb9d1SAndroid Build Coastguard Worker    vrend_renderer_resource_get_info(res->pipe_resource,
476*bbecb9d1SAndroid Build Coastguard Worker                                     (struct vrend_renderer_resource_info *)info);
477*bbecb9d1SAndroid Build Coastguard Worker    info->handle = res_handle;
478*bbecb9d1SAndroid Build Coastguard Worker 
479*bbecb9d1SAndroid Build Coastguard Worker    if (state.winsys_initialized) {
480*bbecb9d1SAndroid Build Coastguard Worker       return vrend_winsys_get_fourcc_for_texture(info->tex_id,
481*bbecb9d1SAndroid Build Coastguard Worker                                                  info->virgl_format,
482*bbecb9d1SAndroid Build Coastguard Worker                                                  &info->drm_fourcc);
483*bbecb9d1SAndroid Build Coastguard Worker    }
484*bbecb9d1SAndroid Build Coastguard Worker 
485*bbecb9d1SAndroid Build Coastguard Worker    return 0;
486*bbecb9d1SAndroid Build Coastguard Worker }
487*bbecb9d1SAndroid Build Coastguard Worker 
virgl_renderer_get_cap_set(uint32_t cap_set,uint32_t * max_ver,uint32_t * max_size)488*bbecb9d1SAndroid Build Coastguard Worker void virgl_renderer_get_cap_set(uint32_t cap_set, uint32_t *max_ver,
489*bbecb9d1SAndroid Build Coastguard Worker                                 uint32_t *max_size)
490*bbecb9d1SAndroid Build Coastguard Worker {
491*bbecb9d1SAndroid Build Coastguard Worker    TRACE_FUNC();
492*bbecb9d1SAndroid Build Coastguard Worker 
493*bbecb9d1SAndroid Build Coastguard Worker    /* this may be called before virgl_renderer_init */
494*bbecb9d1SAndroid Build Coastguard Worker    switch (cap_set) {
495*bbecb9d1SAndroid Build Coastguard Worker    case VIRGL_RENDERER_CAPSET_VIRGL:
496*bbecb9d1SAndroid Build Coastguard Worker    case VIRGL_RENDERER_CAPSET_VIRGL2:
497*bbecb9d1SAndroid Build Coastguard Worker       vrend_renderer_get_cap_set(cap_set, max_ver, max_size);
498*bbecb9d1SAndroid Build Coastguard Worker       break;
499*bbecb9d1SAndroid Build Coastguard Worker    case VIRGL_RENDERER_CAPSET_VENUS:
500*bbecb9d1SAndroid Build Coastguard Worker       *max_ver = 0;
501*bbecb9d1SAndroid Build Coastguard Worker       *max_size = vkr_get_capset(NULL);
502*bbecb9d1SAndroid Build Coastguard Worker       break;
503*bbecb9d1SAndroid Build Coastguard Worker    case VIRGL_RENDERER_CAPSET_DRM:
504*bbecb9d1SAndroid Build Coastguard Worker       *max_ver = 0;
505*bbecb9d1SAndroid Build Coastguard Worker       *max_size = drm_renderer_capset(NULL);
506*bbecb9d1SAndroid Build Coastguard Worker       break;
507*bbecb9d1SAndroid Build Coastguard Worker    default:
508*bbecb9d1SAndroid Build Coastguard Worker       *max_ver = 0;
509*bbecb9d1SAndroid Build Coastguard Worker       *max_size = 0;
510*bbecb9d1SAndroid Build Coastguard Worker       break;
511*bbecb9d1SAndroid Build Coastguard Worker    }
512*bbecb9d1SAndroid Build Coastguard Worker }
513*bbecb9d1SAndroid Build Coastguard Worker 
virgl_renderer_get_rect(int resource_id,struct iovec * iov,unsigned int num_iovs,uint32_t offset,int x,int y,int width,int height)514*bbecb9d1SAndroid Build Coastguard Worker void virgl_renderer_get_rect(int resource_id, struct iovec *iov, unsigned int num_iovs,
515*bbecb9d1SAndroid Build Coastguard Worker                              uint32_t offset, int x, int y, int width, int height)
516*bbecb9d1SAndroid Build Coastguard Worker {
517*bbecb9d1SAndroid Build Coastguard Worker    TRACE_FUNC();
518*bbecb9d1SAndroid Build Coastguard Worker    struct virgl_resource *res = virgl_resource_lookup(resource_id);
519*bbecb9d1SAndroid Build Coastguard Worker    if (!res || !res->pipe_resource)
520*bbecb9d1SAndroid Build Coastguard Worker       return;
521*bbecb9d1SAndroid Build Coastguard Worker 
522*bbecb9d1SAndroid Build Coastguard Worker    vrend_renderer_get_rect(res->pipe_resource, iov, num_iovs, offset, x, y,
523*bbecb9d1SAndroid Build Coastguard Worker                            width, height);
524*bbecb9d1SAndroid Build Coastguard Worker }
525*bbecb9d1SAndroid Build Coastguard Worker 
526*bbecb9d1SAndroid Build Coastguard Worker 
ctx0_fence_retire(uint64_t fence_id,UNUSED void * retire_data)527*bbecb9d1SAndroid Build Coastguard Worker static void ctx0_fence_retire(uint64_t fence_id, UNUSED void *retire_data)
528*bbecb9d1SAndroid Build Coastguard Worker {
529*bbecb9d1SAndroid Build Coastguard Worker    // ctx0 fence_id is created from uint32_t but stored internally as uint64_t,
530*bbecb9d1SAndroid Build Coastguard Worker    // so casting back to uint32_t doesn't result in data loss.
531*bbecb9d1SAndroid Build Coastguard Worker    assert((fence_id >> 32) == 0);
532*bbecb9d1SAndroid Build Coastguard Worker    state.cbs->write_fence(state.cookie, (uint32_t)fence_id);
533*bbecb9d1SAndroid Build Coastguard Worker }
534*bbecb9d1SAndroid Build Coastguard Worker 
create_gl_context(int scanout_idx,struct virgl_gl_ctx_param * param)535*bbecb9d1SAndroid Build Coastguard Worker static virgl_renderer_gl_context create_gl_context(int scanout_idx, struct virgl_gl_ctx_param *param)
536*bbecb9d1SAndroid Build Coastguard Worker {
537*bbecb9d1SAndroid Build Coastguard Worker    struct virgl_renderer_gl_ctx_param vparam;
538*bbecb9d1SAndroid Build Coastguard Worker 
539*bbecb9d1SAndroid Build Coastguard Worker    if (state.winsys_initialized)
540*bbecb9d1SAndroid Build Coastguard Worker       return vrend_winsys_create_context(param);
541*bbecb9d1SAndroid Build Coastguard Worker 
542*bbecb9d1SAndroid Build Coastguard Worker    vparam.version = 1;
543*bbecb9d1SAndroid Build Coastguard Worker    vparam.shared = param->shared;
544*bbecb9d1SAndroid Build Coastguard Worker    vparam.major_ver = param->major_ver;
545*bbecb9d1SAndroid Build Coastguard Worker    vparam.minor_ver = param->minor_ver;
546*bbecb9d1SAndroid Build Coastguard Worker    return state.cbs->create_gl_context(state.cookie, scanout_idx, &vparam);
547*bbecb9d1SAndroid Build Coastguard Worker }
548*bbecb9d1SAndroid Build Coastguard Worker 
destroy_gl_context(virgl_renderer_gl_context ctx)549*bbecb9d1SAndroid Build Coastguard Worker static void destroy_gl_context(virgl_renderer_gl_context ctx)
550*bbecb9d1SAndroid Build Coastguard Worker {
551*bbecb9d1SAndroid Build Coastguard Worker    if (state.winsys_initialized) {
552*bbecb9d1SAndroid Build Coastguard Worker       vrend_winsys_destroy_context(ctx);
553*bbecb9d1SAndroid Build Coastguard Worker       return;
554*bbecb9d1SAndroid Build Coastguard Worker    }
555*bbecb9d1SAndroid Build Coastguard Worker 
556*bbecb9d1SAndroid Build Coastguard Worker    state.cbs->destroy_gl_context(state.cookie, ctx);
557*bbecb9d1SAndroid Build Coastguard Worker }
558*bbecb9d1SAndroid Build Coastguard Worker 
make_current(virgl_renderer_gl_context ctx)559*bbecb9d1SAndroid Build Coastguard Worker static int make_current(virgl_renderer_gl_context ctx)
560*bbecb9d1SAndroid Build Coastguard Worker {
561*bbecb9d1SAndroid Build Coastguard Worker    if (state.winsys_initialized)
562*bbecb9d1SAndroid Build Coastguard Worker       return vrend_winsys_make_context_current(ctx);
563*bbecb9d1SAndroid Build Coastguard Worker 
564*bbecb9d1SAndroid Build Coastguard Worker    return state.cbs->make_current(state.cookie, 0, ctx);
565*bbecb9d1SAndroid Build Coastguard Worker }
566*bbecb9d1SAndroid Build Coastguard Worker 
get_drm_fd(void)567*bbecb9d1SAndroid Build Coastguard Worker static int get_drm_fd(void)
568*bbecb9d1SAndroid Build Coastguard Worker {
569*bbecb9d1SAndroid Build Coastguard Worker    if (state.cbs->get_drm_fd)
570*bbecb9d1SAndroid Build Coastguard Worker       return state.cbs->get_drm_fd(state.cookie);
571*bbecb9d1SAndroid Build Coastguard Worker 
572*bbecb9d1SAndroid Build Coastguard Worker    return -1;
573*bbecb9d1SAndroid Build Coastguard Worker }
574*bbecb9d1SAndroid Build Coastguard Worker 
575*bbecb9d1SAndroid Build Coastguard Worker static const struct vrend_if_cbs vrend_cbs = {
576*bbecb9d1SAndroid Build Coastguard Worker    ctx0_fence_retire,
577*bbecb9d1SAndroid Build Coastguard Worker    create_gl_context,
578*bbecb9d1SAndroid Build Coastguard Worker    destroy_gl_context,
579*bbecb9d1SAndroid Build Coastguard Worker    make_current,
580*bbecb9d1SAndroid Build Coastguard Worker    get_drm_fd,
581*bbecb9d1SAndroid Build Coastguard Worker };
582*bbecb9d1SAndroid Build Coastguard Worker 
583*bbecb9d1SAndroid Build Coastguard Worker static int
proxy_renderer_cb_get_server_fd(uint32_t version)584*bbecb9d1SAndroid Build Coastguard Worker proxy_renderer_cb_get_server_fd(uint32_t version)
585*bbecb9d1SAndroid Build Coastguard Worker {
586*bbecb9d1SAndroid Build Coastguard Worker    if (state.cbs && state.cbs->version >= 3 && state.cbs->get_server_fd)
587*bbecb9d1SAndroid Build Coastguard Worker       return state.cbs->get_server_fd(state.cookie, version);
588*bbecb9d1SAndroid Build Coastguard Worker    else
589*bbecb9d1SAndroid Build Coastguard Worker       return -1;
590*bbecb9d1SAndroid Build Coastguard Worker }
591*bbecb9d1SAndroid Build Coastguard Worker 
592*bbecb9d1SAndroid Build Coastguard Worker static const struct proxy_renderer_cbs proxy_cbs = {
593*bbecb9d1SAndroid Build Coastguard Worker    proxy_renderer_cb_get_server_fd,
594*bbecb9d1SAndroid Build Coastguard Worker };
595*bbecb9d1SAndroid Build Coastguard Worker 
virgl_renderer_get_cursor_data(uint32_t resource_id,uint32_t * width,uint32_t * height)596*bbecb9d1SAndroid Build Coastguard Worker void *virgl_renderer_get_cursor_data(uint32_t resource_id, uint32_t *width, uint32_t *height)
597*bbecb9d1SAndroid Build Coastguard Worker {
598*bbecb9d1SAndroid Build Coastguard Worker    struct virgl_resource *res = virgl_resource_lookup(resource_id);
599*bbecb9d1SAndroid Build Coastguard Worker    if (!res || !res->pipe_resource)
600*bbecb9d1SAndroid Build Coastguard Worker       return NULL;
601*bbecb9d1SAndroid Build Coastguard Worker 
602*bbecb9d1SAndroid Build Coastguard Worker    vrend_renderer_force_ctx_0();
603*bbecb9d1SAndroid Build Coastguard Worker    return vrend_renderer_get_cursor_contents(res->pipe_resource,
604*bbecb9d1SAndroid Build Coastguard Worker                                              width,
605*bbecb9d1SAndroid Build Coastguard Worker                                              height);
606*bbecb9d1SAndroid Build Coastguard Worker }
607*bbecb9d1SAndroid Build Coastguard Worker 
608*bbecb9d1SAndroid Build Coastguard Worker static bool
virgl_context_foreach_retire_fences(struct virgl_context * ctx,UNUSED void * data)609*bbecb9d1SAndroid Build Coastguard Worker virgl_context_foreach_retire_fences(struct virgl_context *ctx,
610*bbecb9d1SAndroid Build Coastguard Worker                                     UNUSED void* data)
611*bbecb9d1SAndroid Build Coastguard Worker {
612*bbecb9d1SAndroid Build Coastguard Worker    /* vrend contexts are polled explicitly by the caller */
613*bbecb9d1SAndroid Build Coastguard Worker    if (ctx->capset_id != VIRGL_RENDERER_CAPSET_VIRGL &&
614*bbecb9d1SAndroid Build Coastguard Worker        ctx->capset_id != VIRGL_RENDERER_CAPSET_VIRGL2)
615*bbecb9d1SAndroid Build Coastguard Worker    {
616*bbecb9d1SAndroid Build Coastguard Worker       assert(ctx->retire_fences);
617*bbecb9d1SAndroid Build Coastguard Worker       ctx->retire_fences(ctx);
618*bbecb9d1SAndroid Build Coastguard Worker    }
619*bbecb9d1SAndroid Build Coastguard Worker    return true;
620*bbecb9d1SAndroid Build Coastguard Worker }
621*bbecb9d1SAndroid Build Coastguard Worker 
virgl_renderer_poll(void)622*bbecb9d1SAndroid Build Coastguard Worker void virgl_renderer_poll(void)
623*bbecb9d1SAndroid Build Coastguard Worker {
624*bbecb9d1SAndroid Build Coastguard Worker    TRACE_FUNC();
625*bbecb9d1SAndroid Build Coastguard Worker    if (state.vrend_initialized)
626*bbecb9d1SAndroid Build Coastguard Worker       vrend_renderer_poll();
627*bbecb9d1SAndroid Build Coastguard Worker 
628*bbecb9d1SAndroid Build Coastguard Worker    struct virgl_context_foreach_args args;
629*bbecb9d1SAndroid Build Coastguard Worker    args.callback = virgl_context_foreach_retire_fences;
630*bbecb9d1SAndroid Build Coastguard Worker    virgl_context_foreach(&args);
631*bbecb9d1SAndroid Build Coastguard Worker }
632*bbecb9d1SAndroid Build Coastguard Worker 
virgl_renderer_cleanup(UNUSED void * cookie)633*bbecb9d1SAndroid Build Coastguard Worker void virgl_renderer_cleanup(UNUSED void *cookie)
634*bbecb9d1SAndroid Build Coastguard Worker {
635*bbecb9d1SAndroid Build Coastguard Worker    TRACE_FUNC();
636*bbecb9d1SAndroid Build Coastguard Worker    if (state.vrend_initialized)
637*bbecb9d1SAndroid Build Coastguard Worker       vrend_renderer_prepare_reset();
638*bbecb9d1SAndroid Build Coastguard Worker 
639*bbecb9d1SAndroid Build Coastguard Worker    if (state.context_initialized)
640*bbecb9d1SAndroid Build Coastguard Worker       virgl_context_table_cleanup();
641*bbecb9d1SAndroid Build Coastguard Worker 
642*bbecb9d1SAndroid Build Coastguard Worker    if (state.resource_initialized)
643*bbecb9d1SAndroid Build Coastguard Worker       virgl_resource_table_cleanup();
644*bbecb9d1SAndroid Build Coastguard Worker 
645*bbecb9d1SAndroid Build Coastguard Worker    if (state.proxy_initialized)
646*bbecb9d1SAndroid Build Coastguard Worker       proxy_renderer_fini();
647*bbecb9d1SAndroid Build Coastguard Worker 
648*bbecb9d1SAndroid Build Coastguard Worker    if (state.vkr_initialized) {
649*bbecb9d1SAndroid Build Coastguard Worker       vkr_renderer_fini();
650*bbecb9d1SAndroid Build Coastguard Worker       /* vkr_allocator_init is called on-demand upon the first map */
651*bbecb9d1SAndroid Build Coastguard Worker       vkr_allocator_fini();
652*bbecb9d1SAndroid Build Coastguard Worker    }
653*bbecb9d1SAndroid Build Coastguard Worker 
654*bbecb9d1SAndroid Build Coastguard Worker    if (state.vrend_initialized)
655*bbecb9d1SAndroid Build Coastguard Worker       vrend_renderer_fini();
656*bbecb9d1SAndroid Build Coastguard Worker 
657*bbecb9d1SAndroid Build Coastguard Worker    if (state.winsys_initialized || state.external_winsys_initialized)
658*bbecb9d1SAndroid Build Coastguard Worker       vrend_winsys_cleanup();
659*bbecb9d1SAndroid Build Coastguard Worker 
660*bbecb9d1SAndroid Build Coastguard Worker    drm_renderer_fini();
661*bbecb9d1SAndroid Build Coastguard Worker 
662*bbecb9d1SAndroid Build Coastguard Worker    memset(&state, 0, sizeof(state));
663*bbecb9d1SAndroid Build Coastguard Worker }
664*bbecb9d1SAndroid Build Coastguard Worker 
virgl_renderer_init(void * cookie,int flags,struct virgl_renderer_callbacks * cbs)665*bbecb9d1SAndroid Build Coastguard Worker int virgl_renderer_init(void *cookie, int flags, struct virgl_renderer_callbacks *cbs)
666*bbecb9d1SAndroid Build Coastguard Worker {
667*bbecb9d1SAndroid Build Coastguard Worker    TRACE_INIT();
668*bbecb9d1SAndroid Build Coastguard Worker    TRACE_FUNC();
669*bbecb9d1SAndroid Build Coastguard Worker 
670*bbecb9d1SAndroid Build Coastguard Worker    int ret;
671*bbecb9d1SAndroid Build Coastguard Worker 
672*bbecb9d1SAndroid Build Coastguard Worker    /* VIRGL_RENDERER_THREAD_SYNC is a hint and can be silently ignored */
673*bbecb9d1SAndroid Build Coastguard Worker    if (!has_eventfd() || getenv("VIRGL_DISABLE_MT"))
674*bbecb9d1SAndroid Build Coastguard Worker       flags &= ~VIRGL_RENDERER_THREAD_SYNC;
675*bbecb9d1SAndroid Build Coastguard Worker 
676*bbecb9d1SAndroid Build Coastguard Worker    if (state.client_initialized && (state.cookie != cookie ||
677*bbecb9d1SAndroid Build Coastguard Worker                                     state.flags != flags ||
678*bbecb9d1SAndroid Build Coastguard Worker                                     state.cbs != cbs))
679*bbecb9d1SAndroid Build Coastguard Worker       return -EBUSY;
680*bbecb9d1SAndroid Build Coastguard Worker 
681*bbecb9d1SAndroid Build Coastguard Worker    if (!state.client_initialized) {
682*bbecb9d1SAndroid Build Coastguard Worker       if (!cbs ||
683*bbecb9d1SAndroid Build Coastguard Worker           cbs->version < 1 ||
684*bbecb9d1SAndroid Build Coastguard Worker           cbs->version > VIRGL_RENDERER_CALLBACKS_VERSION)
685*bbecb9d1SAndroid Build Coastguard Worker          return -1;
686*bbecb9d1SAndroid Build Coastguard Worker 
687*bbecb9d1SAndroid Build Coastguard Worker       state.cookie = cookie;
688*bbecb9d1SAndroid Build Coastguard Worker       state.flags = flags;
689*bbecb9d1SAndroid Build Coastguard Worker       state.cbs = cbs;
690*bbecb9d1SAndroid Build Coastguard Worker       state.client_initialized = true;
691*bbecb9d1SAndroid Build Coastguard Worker    }
692*bbecb9d1SAndroid Build Coastguard Worker 
693*bbecb9d1SAndroid Build Coastguard Worker    if (!state.resource_initialized) {
694*bbecb9d1SAndroid Build Coastguard Worker       const struct virgl_resource_pipe_callbacks *pipe_cbs =
695*bbecb9d1SAndroid Build Coastguard Worker          (flags & VIRGL_RENDERER_NO_VIRGL) ? NULL :
696*bbecb9d1SAndroid Build Coastguard Worker          vrend_renderer_get_pipe_callbacks();
697*bbecb9d1SAndroid Build Coastguard Worker 
698*bbecb9d1SAndroid Build Coastguard Worker       ret = virgl_resource_table_init(pipe_cbs);
699*bbecb9d1SAndroid Build Coastguard Worker       if (ret)
700*bbecb9d1SAndroid Build Coastguard Worker          goto fail;
701*bbecb9d1SAndroid Build Coastguard Worker       state.resource_initialized = true;
702*bbecb9d1SAndroid Build Coastguard Worker    }
703*bbecb9d1SAndroid Build Coastguard Worker 
704*bbecb9d1SAndroid Build Coastguard Worker    if (!state.context_initialized) {
705*bbecb9d1SAndroid Build Coastguard Worker       ret = virgl_context_table_init();
706*bbecb9d1SAndroid Build Coastguard Worker       if (ret)
707*bbecb9d1SAndroid Build Coastguard Worker          goto fail;
708*bbecb9d1SAndroid Build Coastguard Worker       state.context_initialized = true;
709*bbecb9d1SAndroid Build Coastguard Worker    }
710*bbecb9d1SAndroid Build Coastguard Worker 
711*bbecb9d1SAndroid Build Coastguard Worker    if (!state.winsys_initialized && !(flags & VIRGL_RENDERER_NO_VIRGL) &&
712*bbecb9d1SAndroid Build Coastguard Worker        (flags & (VIRGL_RENDERER_USE_EGL | VIRGL_RENDERER_USE_GLX))) {
713*bbecb9d1SAndroid Build Coastguard Worker       int drm_fd = -1;
714*bbecb9d1SAndroid Build Coastguard Worker 
715*bbecb9d1SAndroid Build Coastguard Worker       if (flags & VIRGL_RENDERER_USE_EGL) {
716*bbecb9d1SAndroid Build Coastguard Worker          if (cbs->version >= 2 && cbs->get_drm_fd)
717*bbecb9d1SAndroid Build Coastguard Worker             drm_fd = cbs->get_drm_fd(cookie);
718*bbecb9d1SAndroid Build Coastguard Worker       }
719*bbecb9d1SAndroid Build Coastguard Worker 
720*bbecb9d1SAndroid Build Coastguard Worker       ret = vrend_winsys_init(flags, drm_fd);
721*bbecb9d1SAndroid Build Coastguard Worker       if (ret) {
722*bbecb9d1SAndroid Build Coastguard Worker          if (drm_fd >= 0)
723*bbecb9d1SAndroid Build Coastguard Worker             close(drm_fd);
724*bbecb9d1SAndroid Build Coastguard Worker          goto fail;
725*bbecb9d1SAndroid Build Coastguard Worker       }
726*bbecb9d1SAndroid Build Coastguard Worker       state.winsys_initialized = true;
727*bbecb9d1SAndroid Build Coastguard Worker    }
728*bbecb9d1SAndroid Build Coastguard Worker 
729*bbecb9d1SAndroid Build Coastguard Worker    if (!state.winsys_initialized && !state.external_winsys_initialized &&
730*bbecb9d1SAndroid Build Coastguard Worker        state.cbs && state.cbs->version >= 4 && state.cbs->get_egl_display) {
731*bbecb9d1SAndroid Build Coastguard Worker       void *egl_display = NULL;
732*bbecb9d1SAndroid Build Coastguard Worker 
733*bbecb9d1SAndroid Build Coastguard Worker       if (!cbs->create_gl_context || !cbs->destroy_gl_context ||
734*bbecb9d1SAndroid Build Coastguard Worker           !cbs->make_current) {
735*bbecb9d1SAndroid Build Coastguard Worker          ret = EINVAL;
736*bbecb9d1SAndroid Build Coastguard Worker          goto fail;
737*bbecb9d1SAndroid Build Coastguard Worker       }
738*bbecb9d1SAndroid Build Coastguard Worker 
739*bbecb9d1SAndroid Build Coastguard Worker       egl_display = state.cbs->get_egl_display(cookie);
740*bbecb9d1SAndroid Build Coastguard Worker 
741*bbecb9d1SAndroid Build Coastguard Worker       if (!egl_display) {
742*bbecb9d1SAndroid Build Coastguard Worker          ret = -1;
743*bbecb9d1SAndroid Build Coastguard Worker          goto fail;
744*bbecb9d1SAndroid Build Coastguard Worker       }
745*bbecb9d1SAndroid Build Coastguard Worker       ret = vrend_winsys_init_external(egl_display);
746*bbecb9d1SAndroid Build Coastguard Worker 
747*bbecb9d1SAndroid Build Coastguard Worker       if (ret) {
748*bbecb9d1SAndroid Build Coastguard Worker          ret = -1;
749*bbecb9d1SAndroid Build Coastguard Worker          goto fail;
750*bbecb9d1SAndroid Build Coastguard Worker       }
751*bbecb9d1SAndroid Build Coastguard Worker 
752*bbecb9d1SAndroid Build Coastguard Worker       state.external_winsys_initialized = true;
753*bbecb9d1SAndroid Build Coastguard Worker    }
754*bbecb9d1SAndroid Build Coastguard Worker 
755*bbecb9d1SAndroid Build Coastguard Worker    if (!state.vrend_initialized && !(flags & VIRGL_RENDERER_NO_VIRGL)) {
756*bbecb9d1SAndroid Build Coastguard Worker       uint32_t renderer_flags = 0;
757*bbecb9d1SAndroid Build Coastguard Worker 
758*bbecb9d1SAndroid Build Coastguard Worker       if (!cookie || !cbs) {
759*bbecb9d1SAndroid Build Coastguard Worker          ret = -1;
760*bbecb9d1SAndroid Build Coastguard Worker          goto fail;
761*bbecb9d1SAndroid Build Coastguard Worker       }
762*bbecb9d1SAndroid Build Coastguard Worker 
763*bbecb9d1SAndroid Build Coastguard Worker       if (flags & VIRGL_RENDERER_THREAD_SYNC)
764*bbecb9d1SAndroid Build Coastguard Worker          renderer_flags |= VREND_USE_THREAD_SYNC;
765*bbecb9d1SAndroid Build Coastguard Worker       if (flags & VIRGL_RENDERER_ASYNC_FENCE_CB)
766*bbecb9d1SAndroid Build Coastguard Worker          renderer_flags |= VREND_USE_ASYNC_FENCE_CB;
767*bbecb9d1SAndroid Build Coastguard Worker       if (flags & VIRGL_RENDERER_USE_EXTERNAL_BLOB)
768*bbecb9d1SAndroid Build Coastguard Worker          renderer_flags |= VREND_USE_EXTERNAL_BLOB;
769*bbecb9d1SAndroid Build Coastguard Worker       if (flags & VIRGL_RENDERER_USE_VIDEO)
770*bbecb9d1SAndroid Build Coastguard Worker          renderer_flags |= VREND_USE_VIDEO;
771*bbecb9d1SAndroid Build Coastguard Worker 
772*bbecb9d1SAndroid Build Coastguard Worker       ret = vrend_renderer_init(&vrend_cbs, renderer_flags);
773*bbecb9d1SAndroid Build Coastguard Worker       if (ret)
774*bbecb9d1SAndroid Build Coastguard Worker          goto fail;
775*bbecb9d1SAndroid Build Coastguard Worker       state.vrend_initialized = true;
776*bbecb9d1SAndroid Build Coastguard Worker    }
777*bbecb9d1SAndroid Build Coastguard Worker 
778*bbecb9d1SAndroid Build Coastguard Worker    if (!state.vkr_initialized && (flags & VIRGL_RENDERER_VENUS)) {
779*bbecb9d1SAndroid Build Coastguard Worker       uint32_t vkr_flags = 0;
780*bbecb9d1SAndroid Build Coastguard Worker       if (flags & VIRGL_RENDERER_THREAD_SYNC)
781*bbecb9d1SAndroid Build Coastguard Worker          vkr_flags |= VKR_RENDERER_THREAD_SYNC;
782*bbecb9d1SAndroid Build Coastguard Worker       if (flags & VIRGL_RENDERER_ASYNC_FENCE_CB)
783*bbecb9d1SAndroid Build Coastguard Worker          vkr_flags |= VKR_RENDERER_ASYNC_FENCE_CB;
784*bbecb9d1SAndroid Build Coastguard Worker       if (flags & VIRGL_RENDERER_RENDER_SERVER)
785*bbecb9d1SAndroid Build Coastguard Worker          vkr_flags |= VKR_RENDERER_RENDER_SERVER;
786*bbecb9d1SAndroid Build Coastguard Worker 
787*bbecb9d1SAndroid Build Coastguard Worker       ret = vkr_renderer_init(vkr_flags);
788*bbecb9d1SAndroid Build Coastguard Worker       if (ret)
789*bbecb9d1SAndroid Build Coastguard Worker          goto fail;
790*bbecb9d1SAndroid Build Coastguard Worker       state.vkr_initialized = true;
791*bbecb9d1SAndroid Build Coastguard Worker    }
792*bbecb9d1SAndroid Build Coastguard Worker 
793*bbecb9d1SAndroid Build Coastguard Worker    if (!state.proxy_initialized && (flags & VIRGL_RENDERER_RENDER_SERVER)) {
794*bbecb9d1SAndroid Build Coastguard Worker       ret = proxy_renderer_init(&proxy_cbs, flags | VIRGL_RENDERER_NO_VIRGL);
795*bbecb9d1SAndroid Build Coastguard Worker       if (ret)
796*bbecb9d1SAndroid Build Coastguard Worker          goto fail;
797*bbecb9d1SAndroid Build Coastguard Worker       state.proxy_initialized = true;
798*bbecb9d1SAndroid Build Coastguard Worker    }
799*bbecb9d1SAndroid Build Coastguard Worker 
800*bbecb9d1SAndroid Build Coastguard Worker    if ((flags & VIRGL_RENDERER_ASYNC_FENCE_CB) &&
801*bbecb9d1SAndroid Build Coastguard Worker        (flags & VIRGL_RENDERER_DRM)) {
802*bbecb9d1SAndroid Build Coastguard Worker       int drm_fd = -1;
803*bbecb9d1SAndroid Build Coastguard Worker 
804*bbecb9d1SAndroid Build Coastguard Worker       if (cbs->version >= 2 && cbs->get_drm_fd)
805*bbecb9d1SAndroid Build Coastguard Worker          drm_fd = cbs->get_drm_fd(cookie);
806*bbecb9d1SAndroid Build Coastguard Worker 
807*bbecb9d1SAndroid Build Coastguard Worker       drm_renderer_init(drm_fd);
808*bbecb9d1SAndroid Build Coastguard Worker    }
809*bbecb9d1SAndroid Build Coastguard Worker 
810*bbecb9d1SAndroid Build Coastguard Worker    return 0;
811*bbecb9d1SAndroid Build Coastguard Worker 
812*bbecb9d1SAndroid Build Coastguard Worker fail:
813*bbecb9d1SAndroid Build Coastguard Worker    virgl_renderer_cleanup(NULL);
814*bbecb9d1SAndroid Build Coastguard Worker    return ret;
815*bbecb9d1SAndroid Build Coastguard Worker }
816*bbecb9d1SAndroid Build Coastguard Worker 
virgl_renderer_get_fd_for_texture(uint32_t tex_id,int * fd)817*bbecb9d1SAndroid Build Coastguard Worker int virgl_renderer_get_fd_for_texture(uint32_t tex_id, int *fd)
818*bbecb9d1SAndroid Build Coastguard Worker {
819*bbecb9d1SAndroid Build Coastguard Worker    TRACE_FUNC();
820*bbecb9d1SAndroid Build Coastguard Worker    if (state.winsys_initialized)
821*bbecb9d1SAndroid Build Coastguard Worker       return vrend_winsys_get_fd_for_texture(tex_id, fd);
822*bbecb9d1SAndroid Build Coastguard Worker    return -1;
823*bbecb9d1SAndroid Build Coastguard Worker }
824*bbecb9d1SAndroid Build Coastguard Worker 
virgl_renderer_get_fd_for_texture2(uint32_t tex_id,int * fd,int * stride,int * offset)825*bbecb9d1SAndroid Build Coastguard Worker int virgl_renderer_get_fd_for_texture2(uint32_t tex_id, int *fd, int *stride, int *offset)
826*bbecb9d1SAndroid Build Coastguard Worker {
827*bbecb9d1SAndroid Build Coastguard Worker    TRACE_FUNC();
828*bbecb9d1SAndroid Build Coastguard Worker    if (state.winsys_initialized)
829*bbecb9d1SAndroid Build Coastguard Worker       return vrend_winsys_get_fd_for_texture2(tex_id, fd, stride, offset);
830*bbecb9d1SAndroid Build Coastguard Worker    return -1;
831*bbecb9d1SAndroid Build Coastguard Worker }
832*bbecb9d1SAndroid Build Coastguard Worker 
virgl_renderer_reset(void)833*bbecb9d1SAndroid Build Coastguard Worker void virgl_renderer_reset(void)
834*bbecb9d1SAndroid Build Coastguard Worker {
835*bbecb9d1SAndroid Build Coastguard Worker    TRACE_FUNC();
836*bbecb9d1SAndroid Build Coastguard Worker    if (state.vrend_initialized)
837*bbecb9d1SAndroid Build Coastguard Worker       vrend_renderer_prepare_reset();
838*bbecb9d1SAndroid Build Coastguard Worker 
839*bbecb9d1SAndroid Build Coastguard Worker    if (state.context_initialized)
840*bbecb9d1SAndroid Build Coastguard Worker       virgl_context_table_reset();
841*bbecb9d1SAndroid Build Coastguard Worker 
842*bbecb9d1SAndroid Build Coastguard Worker    if (state.resource_initialized)
843*bbecb9d1SAndroid Build Coastguard Worker       virgl_resource_table_reset();
844*bbecb9d1SAndroid Build Coastguard Worker 
845*bbecb9d1SAndroid Build Coastguard Worker    if (state.proxy_initialized)
846*bbecb9d1SAndroid Build Coastguard Worker       proxy_renderer_reset();
847*bbecb9d1SAndroid Build Coastguard Worker 
848*bbecb9d1SAndroid Build Coastguard Worker    if (state.vkr_initialized)
849*bbecb9d1SAndroid Build Coastguard Worker       vkr_renderer_reset();
850*bbecb9d1SAndroid Build Coastguard Worker 
851*bbecb9d1SAndroid Build Coastguard Worker    if (state.vrend_initialized)
852*bbecb9d1SAndroid Build Coastguard Worker       vrend_renderer_reset();
853*bbecb9d1SAndroid Build Coastguard Worker 
854*bbecb9d1SAndroid Build Coastguard Worker    drm_renderer_reset();
855*bbecb9d1SAndroid Build Coastguard Worker }
856*bbecb9d1SAndroid Build Coastguard Worker 
virgl_renderer_get_poll_fd(void)857*bbecb9d1SAndroid Build Coastguard Worker int virgl_renderer_get_poll_fd(void)
858*bbecb9d1SAndroid Build Coastguard Worker {
859*bbecb9d1SAndroid Build Coastguard Worker    TRACE_FUNC();
860*bbecb9d1SAndroid Build Coastguard Worker    if (state.vrend_initialized)
861*bbecb9d1SAndroid Build Coastguard Worker       return vrend_renderer_get_poll_fd();
862*bbecb9d1SAndroid Build Coastguard Worker 
863*bbecb9d1SAndroid Build Coastguard Worker    return -1;
864*bbecb9d1SAndroid Build Coastguard Worker }
865*bbecb9d1SAndroid Build Coastguard Worker 
virgl_set_debug_callback(virgl_debug_callback_type cb)866*bbecb9d1SAndroid Build Coastguard Worker virgl_debug_callback_type virgl_set_debug_callback(virgl_debug_callback_type cb)
867*bbecb9d1SAndroid Build Coastguard Worker {
868*bbecb9d1SAndroid Build Coastguard Worker    return virgl_log_set_logger(cb);
869*bbecb9d1SAndroid Build Coastguard Worker }
870*bbecb9d1SAndroid Build Coastguard Worker 
virgl_renderer_export_query(void * execute_args,uint32_t execute_size)871*bbecb9d1SAndroid Build Coastguard Worker static int virgl_renderer_export_query(void *execute_args, uint32_t execute_size)
872*bbecb9d1SAndroid Build Coastguard Worker {
873*bbecb9d1SAndroid Build Coastguard Worker    struct virgl_resource *res;
874*bbecb9d1SAndroid Build Coastguard Worker    struct virgl_renderer_export_query *export_query = execute_args;
875*bbecb9d1SAndroid Build Coastguard Worker    if (execute_size != sizeof(struct virgl_renderer_export_query))
876*bbecb9d1SAndroid Build Coastguard Worker       return -EINVAL;
877*bbecb9d1SAndroid Build Coastguard Worker 
878*bbecb9d1SAndroid Build Coastguard Worker    if (export_query->hdr.size != sizeof(struct virgl_renderer_export_query))
879*bbecb9d1SAndroid Build Coastguard Worker       return -EINVAL;
880*bbecb9d1SAndroid Build Coastguard Worker 
881*bbecb9d1SAndroid Build Coastguard Worker    res = virgl_resource_lookup(export_query->in_resource_id);
882*bbecb9d1SAndroid Build Coastguard Worker    if (!res)
883*bbecb9d1SAndroid Build Coastguard Worker       return -EINVAL;
884*bbecb9d1SAndroid Build Coastguard Worker 
885*bbecb9d1SAndroid Build Coastguard Worker 
886*bbecb9d1SAndroid Build Coastguard Worker    if (res->pipe_resource) {
887*bbecb9d1SAndroid Build Coastguard Worker       return vrend_renderer_export_query(res->pipe_resource, export_query);
888*bbecb9d1SAndroid Build Coastguard Worker    } else if (!export_query->in_export_fds) {
889*bbecb9d1SAndroid Build Coastguard Worker       /* Untyped resources are expected to be exported with
890*bbecb9d1SAndroid Build Coastguard Worker        * virgl_renderer_resource_export_blob instead and have no type
891*bbecb9d1SAndroid Build Coastguard Worker        * information.  But when this is called to query (in_export_fds is
892*bbecb9d1SAndroid Build Coastguard Worker        * false) an untyped resource, we should return sane values.
893*bbecb9d1SAndroid Build Coastguard Worker        */
894*bbecb9d1SAndroid Build Coastguard Worker       export_query->out_num_fds = 1;
895*bbecb9d1SAndroid Build Coastguard Worker       export_query->out_fourcc = 0;
896*bbecb9d1SAndroid Build Coastguard Worker       export_query->out_fds[0] = -1;
897*bbecb9d1SAndroid Build Coastguard Worker       export_query->out_strides[0] = 0;
898*bbecb9d1SAndroid Build Coastguard Worker       export_query->out_offsets[0] = 0;
899*bbecb9d1SAndroid Build Coastguard Worker       export_query->out_modifier = DRM_FORMAT_MOD_INVALID;
900*bbecb9d1SAndroid Build Coastguard Worker       return 0;
901*bbecb9d1SAndroid Build Coastguard Worker    } else {
902*bbecb9d1SAndroid Build Coastguard Worker       return -EINVAL;
903*bbecb9d1SAndroid Build Coastguard Worker    }
904*bbecb9d1SAndroid Build Coastguard Worker }
905*bbecb9d1SAndroid Build Coastguard Worker 
virgl_renderer_supported_structures(void * execute_args,uint32_t execute_size)906*bbecb9d1SAndroid Build Coastguard Worker static int virgl_renderer_supported_structures(void *execute_args, uint32_t execute_size)
907*bbecb9d1SAndroid Build Coastguard Worker {
908*bbecb9d1SAndroid Build Coastguard Worker    struct virgl_renderer_supported_structures *supported_structures = execute_args;
909*bbecb9d1SAndroid Build Coastguard Worker    if (execute_size != sizeof(struct virgl_renderer_supported_structures))
910*bbecb9d1SAndroid Build Coastguard Worker       return -EINVAL;
911*bbecb9d1SAndroid Build Coastguard Worker 
912*bbecb9d1SAndroid Build Coastguard Worker    if (supported_structures->hdr.size != sizeof(struct virgl_renderer_supported_structures))
913*bbecb9d1SAndroid Build Coastguard Worker       return -EINVAL;
914*bbecb9d1SAndroid Build Coastguard Worker 
915*bbecb9d1SAndroid Build Coastguard Worker    if (supported_structures->in_stype_version == 0) {
916*bbecb9d1SAndroid Build Coastguard Worker       supported_structures->out_supported_structures_mask =
917*bbecb9d1SAndroid Build Coastguard Worker          VIRGL_RENDERER_STRUCTURE_TYPE_EXPORT_QUERY |
918*bbecb9d1SAndroid Build Coastguard Worker          VIRGL_RENDERER_STRUCTURE_TYPE_SUPPORTED_STRUCTURES;
919*bbecb9d1SAndroid Build Coastguard Worker    } else {
920*bbecb9d1SAndroid Build Coastguard Worker       supported_structures->out_supported_structures_mask = 0;
921*bbecb9d1SAndroid Build Coastguard Worker    }
922*bbecb9d1SAndroid Build Coastguard Worker 
923*bbecb9d1SAndroid Build Coastguard Worker    return 0;
924*bbecb9d1SAndroid Build Coastguard Worker }
925*bbecb9d1SAndroid Build Coastguard Worker 
virgl_renderer_execute(void * execute_args,uint32_t execute_size)926*bbecb9d1SAndroid Build Coastguard Worker int virgl_renderer_execute(void *execute_args, uint32_t execute_size)
927*bbecb9d1SAndroid Build Coastguard Worker {
928*bbecb9d1SAndroid Build Coastguard Worker    TRACE_FUNC();
929*bbecb9d1SAndroid Build Coastguard Worker    struct virgl_renderer_hdr *hdr = execute_args;
930*bbecb9d1SAndroid Build Coastguard Worker    if (hdr->stype_version != 0)
931*bbecb9d1SAndroid Build Coastguard Worker       return -EINVAL;
932*bbecb9d1SAndroid Build Coastguard Worker 
933*bbecb9d1SAndroid Build Coastguard Worker    switch (hdr->stype) {
934*bbecb9d1SAndroid Build Coastguard Worker       case VIRGL_RENDERER_STRUCTURE_TYPE_SUPPORTED_STRUCTURES:
935*bbecb9d1SAndroid Build Coastguard Worker          return virgl_renderer_supported_structures(execute_args, execute_size);
936*bbecb9d1SAndroid Build Coastguard Worker       case VIRGL_RENDERER_STRUCTURE_TYPE_EXPORT_QUERY:
937*bbecb9d1SAndroid Build Coastguard Worker          return virgl_renderer_export_query(execute_args, execute_size);
938*bbecb9d1SAndroid Build Coastguard Worker       default:
939*bbecb9d1SAndroid Build Coastguard Worker          return -EINVAL;
940*bbecb9d1SAndroid Build Coastguard Worker    }
941*bbecb9d1SAndroid Build Coastguard Worker }
942*bbecb9d1SAndroid Build Coastguard Worker 
virgl_renderer_resource_create_blob(const struct virgl_renderer_resource_create_blob_args * args)943*bbecb9d1SAndroid Build Coastguard Worker int virgl_renderer_resource_create_blob(const struct virgl_renderer_resource_create_blob_args *args)
944*bbecb9d1SAndroid Build Coastguard Worker {
945*bbecb9d1SAndroid Build Coastguard Worker    TRACE_FUNC();
946*bbecb9d1SAndroid Build Coastguard Worker    struct virgl_resource *res;
947*bbecb9d1SAndroid Build Coastguard Worker    struct virgl_context *ctx;
948*bbecb9d1SAndroid Build Coastguard Worker    struct virgl_context_blob blob;
949*bbecb9d1SAndroid Build Coastguard Worker    bool has_host_storage;
950*bbecb9d1SAndroid Build Coastguard Worker    bool has_guest_storage;
951*bbecb9d1SAndroid Build Coastguard Worker    int ret;
952*bbecb9d1SAndroid Build Coastguard Worker 
953*bbecb9d1SAndroid Build Coastguard Worker    switch (args->blob_mem) {
954*bbecb9d1SAndroid Build Coastguard Worker    case VIRGL_RENDERER_BLOB_MEM_GUEST:
955*bbecb9d1SAndroid Build Coastguard Worker       has_host_storage = false;
956*bbecb9d1SAndroid Build Coastguard Worker       has_guest_storage = true;
957*bbecb9d1SAndroid Build Coastguard Worker       break;
958*bbecb9d1SAndroid Build Coastguard Worker    case VIRGL_RENDERER_BLOB_MEM_HOST3D:
959*bbecb9d1SAndroid Build Coastguard Worker       has_host_storage = true;
960*bbecb9d1SAndroid Build Coastguard Worker       has_guest_storage = false;
961*bbecb9d1SAndroid Build Coastguard Worker       break;
962*bbecb9d1SAndroid Build Coastguard Worker    case VIRGL_RENDERER_BLOB_MEM_HOST3D_GUEST:
963*bbecb9d1SAndroid Build Coastguard Worker       has_host_storage = true;
964*bbecb9d1SAndroid Build Coastguard Worker       has_guest_storage = true;
965*bbecb9d1SAndroid Build Coastguard Worker       break;
966*bbecb9d1SAndroid Build Coastguard Worker    default:
967*bbecb9d1SAndroid Build Coastguard Worker       return -EINVAL;
968*bbecb9d1SAndroid Build Coastguard Worker    }
969*bbecb9d1SAndroid Build Coastguard Worker 
970*bbecb9d1SAndroid Build Coastguard Worker    /* user resource id must be greater than 0 */
971*bbecb9d1SAndroid Build Coastguard Worker    if (args->res_handle == 0)
972*bbecb9d1SAndroid Build Coastguard Worker       return -EINVAL;
973*bbecb9d1SAndroid Build Coastguard Worker 
974*bbecb9d1SAndroid Build Coastguard Worker    /* user resource id must be unique */
975*bbecb9d1SAndroid Build Coastguard Worker    if (virgl_resource_lookup(args->res_handle))
976*bbecb9d1SAndroid Build Coastguard Worker       return -EINVAL;
977*bbecb9d1SAndroid Build Coastguard Worker 
978*bbecb9d1SAndroid Build Coastguard Worker    if (args->size == 0)
979*bbecb9d1SAndroid Build Coastguard Worker       return -EINVAL;
980*bbecb9d1SAndroid Build Coastguard Worker    if (has_guest_storage) {
981*bbecb9d1SAndroid Build Coastguard Worker       const size_t iov_size = vrend_get_iovec_size(args->iovecs, args->num_iovs);
982*bbecb9d1SAndroid Build Coastguard Worker       if (iov_size < args->size)
983*bbecb9d1SAndroid Build Coastguard Worker          return -EINVAL;
984*bbecb9d1SAndroid Build Coastguard Worker    } else {
985*bbecb9d1SAndroid Build Coastguard Worker       if (args->num_iovs)
986*bbecb9d1SAndroid Build Coastguard Worker          return -EINVAL;
987*bbecb9d1SAndroid Build Coastguard Worker    }
988*bbecb9d1SAndroid Build Coastguard Worker 
989*bbecb9d1SAndroid Build Coastguard Worker    if (!has_host_storage) {
990*bbecb9d1SAndroid Build Coastguard Worker       res = virgl_resource_create_from_iov(args->res_handle,
991*bbecb9d1SAndroid Build Coastguard Worker                                            args->iovecs,
992*bbecb9d1SAndroid Build Coastguard Worker                                            args->num_iovs);
993*bbecb9d1SAndroid Build Coastguard Worker       if (!res)
994*bbecb9d1SAndroid Build Coastguard Worker          return -ENOMEM;
995*bbecb9d1SAndroid Build Coastguard Worker 
996*bbecb9d1SAndroid Build Coastguard Worker       res->map_info = VIRGL_RENDERER_MAP_CACHE_CACHED;
997*bbecb9d1SAndroid Build Coastguard Worker       return 0;
998*bbecb9d1SAndroid Build Coastguard Worker    }
999*bbecb9d1SAndroid Build Coastguard Worker 
1000*bbecb9d1SAndroid Build Coastguard Worker    ctx = virgl_context_lookup(args->ctx_id);
1001*bbecb9d1SAndroid Build Coastguard Worker    if (!ctx)
1002*bbecb9d1SAndroid Build Coastguard Worker       return -EINVAL;
1003*bbecb9d1SAndroid Build Coastguard Worker 
1004*bbecb9d1SAndroid Build Coastguard Worker    ret = ctx->get_blob(ctx, args->res_handle, args->blob_id, args->size, args->blob_flags, &blob);
1005*bbecb9d1SAndroid Build Coastguard Worker    if (ret)
1006*bbecb9d1SAndroid Build Coastguard Worker       return ret;
1007*bbecb9d1SAndroid Build Coastguard Worker 
1008*bbecb9d1SAndroid Build Coastguard Worker    if (blob.type == VIRGL_RESOURCE_OPAQUE_HANDLE) {
1009*bbecb9d1SAndroid Build Coastguard Worker       assert(!(args->blob_flags & VIRGL_RENDERER_BLOB_FLAG_USE_SHAREABLE));
1010*bbecb9d1SAndroid Build Coastguard Worker       res = virgl_resource_create_from_opaque_handle(ctx, args->res_handle, blob.u.opaque_handle);
1011*bbecb9d1SAndroid Build Coastguard Worker       if (!res)
1012*bbecb9d1SAndroid Build Coastguard Worker          return -ENOMEM;
1013*bbecb9d1SAndroid Build Coastguard Worker    } else if (blob.type != VIRGL_RESOURCE_FD_INVALID) {
1014*bbecb9d1SAndroid Build Coastguard Worker       res = virgl_resource_create_from_fd(args->res_handle,
1015*bbecb9d1SAndroid Build Coastguard Worker                                           blob.type,
1016*bbecb9d1SAndroid Build Coastguard Worker                                           blob.u.fd,
1017*bbecb9d1SAndroid Build Coastguard Worker                                           args->iovecs,
1018*bbecb9d1SAndroid Build Coastguard Worker                                           args->num_iovs,
1019*bbecb9d1SAndroid Build Coastguard Worker                                           &blob.opaque_fd_metadata);
1020*bbecb9d1SAndroid Build Coastguard Worker       if (!res) {
1021*bbecb9d1SAndroid Build Coastguard Worker          close(blob.u.fd);
1022*bbecb9d1SAndroid Build Coastguard Worker          return -ENOMEM;
1023*bbecb9d1SAndroid Build Coastguard Worker       }
1024*bbecb9d1SAndroid Build Coastguard Worker    } else {
1025*bbecb9d1SAndroid Build Coastguard Worker       res = virgl_resource_create_from_pipe(args->res_handle,
1026*bbecb9d1SAndroid Build Coastguard Worker                                             blob.u.pipe_resource,
1027*bbecb9d1SAndroid Build Coastguard Worker                                             args->iovecs,
1028*bbecb9d1SAndroid Build Coastguard Worker                                             args->num_iovs);
1029*bbecb9d1SAndroid Build Coastguard Worker       if (!res) {
1030*bbecb9d1SAndroid Build Coastguard Worker          vrend_renderer_resource_destroy((struct vrend_resource *)blob.u.pipe_resource);
1031*bbecb9d1SAndroid Build Coastguard Worker          return -ENOMEM;
1032*bbecb9d1SAndroid Build Coastguard Worker       }
1033*bbecb9d1SAndroid Build Coastguard Worker    }
1034*bbecb9d1SAndroid Build Coastguard Worker 
1035*bbecb9d1SAndroid Build Coastguard Worker    res->map_info = blob.map_info;
1036*bbecb9d1SAndroid Build Coastguard Worker    res->map_size = args->size;
1037*bbecb9d1SAndroid Build Coastguard Worker 
1038*bbecb9d1SAndroid Build Coastguard Worker    return 0;
1039*bbecb9d1SAndroid Build Coastguard Worker }
1040*bbecb9d1SAndroid Build Coastguard Worker 
virgl_renderer_resource_map(uint32_t res_handle,void ** out_map,uint64_t * out_size)1041*bbecb9d1SAndroid Build Coastguard Worker int virgl_renderer_resource_map(uint32_t res_handle, void **out_map, uint64_t *out_size)
1042*bbecb9d1SAndroid Build Coastguard Worker {
1043*bbecb9d1SAndroid Build Coastguard Worker    TRACE_FUNC();
1044*bbecb9d1SAndroid Build Coastguard Worker    int ret = 0;
1045*bbecb9d1SAndroid Build Coastguard Worker    void *map = NULL;
1046*bbecb9d1SAndroid Build Coastguard Worker    uint64_t map_size = 0;
1047*bbecb9d1SAndroid Build Coastguard Worker    struct virgl_resource *res = virgl_resource_lookup(res_handle);
1048*bbecb9d1SAndroid Build Coastguard Worker    if (!res || res->mapped)
1049*bbecb9d1SAndroid Build Coastguard Worker       return -EINVAL;
1050*bbecb9d1SAndroid Build Coastguard Worker 
1051*bbecb9d1SAndroid Build Coastguard Worker    if (res->pipe_resource) {
1052*bbecb9d1SAndroid Build Coastguard Worker       ret = vrend_renderer_resource_map(res->pipe_resource, &map, &map_size);
1053*bbecb9d1SAndroid Build Coastguard Worker       if (!ret)
1054*bbecb9d1SAndroid Build Coastguard Worker          res->map_size = map_size;
1055*bbecb9d1SAndroid Build Coastguard Worker    } else {
1056*bbecb9d1SAndroid Build Coastguard Worker       switch (res->fd_type) {
1057*bbecb9d1SAndroid Build Coastguard Worker       case VIRGL_RESOURCE_FD_DMABUF:
1058*bbecb9d1SAndroid Build Coastguard Worker       case VIRGL_RESOURCE_FD_SHM:
1059*bbecb9d1SAndroid Build Coastguard Worker          map = mmap(NULL, res->map_size, PROT_WRITE | PROT_READ, MAP_SHARED, res->fd, 0);
1060*bbecb9d1SAndroid Build Coastguard Worker          map_size = res->map_size;
1061*bbecb9d1SAndroid Build Coastguard Worker          break;
1062*bbecb9d1SAndroid Build Coastguard Worker       case VIRGL_RESOURCE_FD_OPAQUE:
1063*bbecb9d1SAndroid Build Coastguard Worker          ret = vkr_allocator_resource_map(res, &map, &map_size);
1064*bbecb9d1SAndroid Build Coastguard Worker          break;
1065*bbecb9d1SAndroid Build Coastguard Worker       default:
1066*bbecb9d1SAndroid Build Coastguard Worker          break;
1067*bbecb9d1SAndroid Build Coastguard Worker       }
1068*bbecb9d1SAndroid Build Coastguard Worker    }
1069*bbecb9d1SAndroid Build Coastguard Worker 
1070*bbecb9d1SAndroid Build Coastguard Worker    if (!map || map == MAP_FAILED)
1071*bbecb9d1SAndroid Build Coastguard Worker       return -EINVAL;
1072*bbecb9d1SAndroid Build Coastguard Worker 
1073*bbecb9d1SAndroid Build Coastguard Worker    res->mapped = map;
1074*bbecb9d1SAndroid Build Coastguard Worker    *out_map = map;
1075*bbecb9d1SAndroid Build Coastguard Worker    *out_size = map_size;
1076*bbecb9d1SAndroid Build Coastguard Worker    return ret;
1077*bbecb9d1SAndroid Build Coastguard Worker }
1078*bbecb9d1SAndroid Build Coastguard Worker 
virgl_renderer_resource_unmap(uint32_t res_handle)1079*bbecb9d1SAndroid Build Coastguard Worker int virgl_renderer_resource_unmap(uint32_t res_handle)
1080*bbecb9d1SAndroid Build Coastguard Worker {
1081*bbecb9d1SAndroid Build Coastguard Worker    TRACE_FUNC();
1082*bbecb9d1SAndroid Build Coastguard Worker    int ret;
1083*bbecb9d1SAndroid Build Coastguard Worker    struct virgl_resource *res = virgl_resource_lookup(res_handle);
1084*bbecb9d1SAndroid Build Coastguard Worker    if (!res || !res->mapped)
1085*bbecb9d1SAndroid Build Coastguard Worker       return -EINVAL;
1086*bbecb9d1SAndroid Build Coastguard Worker 
1087*bbecb9d1SAndroid Build Coastguard Worker    if (res->pipe_resource) {
1088*bbecb9d1SAndroid Build Coastguard Worker       ret = vrend_renderer_resource_unmap(res->pipe_resource);
1089*bbecb9d1SAndroid Build Coastguard Worker    } else {
1090*bbecb9d1SAndroid Build Coastguard Worker       switch (res->fd_type) {
1091*bbecb9d1SAndroid Build Coastguard Worker       case VIRGL_RESOURCE_FD_DMABUF:
1092*bbecb9d1SAndroid Build Coastguard Worker          ret = munmap(res->mapped, res->map_size);
1093*bbecb9d1SAndroid Build Coastguard Worker          break;
1094*bbecb9d1SAndroid Build Coastguard Worker       case VIRGL_RESOURCE_FD_OPAQUE:
1095*bbecb9d1SAndroid Build Coastguard Worker          ret = vkr_allocator_resource_unmap(res);
1096*bbecb9d1SAndroid Build Coastguard Worker          break;
1097*bbecb9d1SAndroid Build Coastguard Worker       default:
1098*bbecb9d1SAndroid Build Coastguard Worker          ret = -EINVAL;
1099*bbecb9d1SAndroid Build Coastguard Worker          break;
1100*bbecb9d1SAndroid Build Coastguard Worker       }
1101*bbecb9d1SAndroid Build Coastguard Worker    }
1102*bbecb9d1SAndroid Build Coastguard Worker 
1103*bbecb9d1SAndroid Build Coastguard Worker    assert(!ret);
1104*bbecb9d1SAndroid Build Coastguard Worker    res->mapped = NULL;
1105*bbecb9d1SAndroid Build Coastguard Worker    return ret;
1106*bbecb9d1SAndroid Build Coastguard Worker }
1107*bbecb9d1SAndroid Build Coastguard Worker 
virgl_renderer_resource_get_map_info(uint32_t res_handle,uint32_t * map_info)1108*bbecb9d1SAndroid Build Coastguard Worker int virgl_renderer_resource_get_map_info(uint32_t res_handle, uint32_t *map_info)
1109*bbecb9d1SAndroid Build Coastguard Worker {
1110*bbecb9d1SAndroid Build Coastguard Worker    TRACE_FUNC();
1111*bbecb9d1SAndroid Build Coastguard Worker    struct virgl_resource *res = virgl_resource_lookup(res_handle);
1112*bbecb9d1SAndroid Build Coastguard Worker    if (!res)
1113*bbecb9d1SAndroid Build Coastguard Worker       return -EINVAL;
1114*bbecb9d1SAndroid Build Coastguard Worker 
1115*bbecb9d1SAndroid Build Coastguard Worker    if ((res->map_info & VIRGL_RENDERER_MAP_CACHE_MASK) ==
1116*bbecb9d1SAndroid Build Coastguard Worker        VIRGL_RENDERER_MAP_CACHE_NONE)
1117*bbecb9d1SAndroid Build Coastguard Worker       return -EINVAL;
1118*bbecb9d1SAndroid Build Coastguard Worker 
1119*bbecb9d1SAndroid Build Coastguard Worker    *map_info = res->map_info;
1120*bbecb9d1SAndroid Build Coastguard Worker    return 0;
1121*bbecb9d1SAndroid Build Coastguard Worker }
1122*bbecb9d1SAndroid Build Coastguard Worker 
1123*bbecb9d1SAndroid Build Coastguard Worker int
virgl_renderer_resource_export_blob(uint32_t res_id,uint32_t * fd_type,int * fd)1124*bbecb9d1SAndroid Build Coastguard Worker virgl_renderer_resource_export_blob(uint32_t res_id, uint32_t *fd_type, int *fd)
1125*bbecb9d1SAndroid Build Coastguard Worker {
1126*bbecb9d1SAndroid Build Coastguard Worker    TRACE_FUNC();
1127*bbecb9d1SAndroid Build Coastguard Worker    struct virgl_resource *res = virgl_resource_lookup(res_id);
1128*bbecb9d1SAndroid Build Coastguard Worker    if (!res)
1129*bbecb9d1SAndroid Build Coastguard Worker       return EINVAL;
1130*bbecb9d1SAndroid Build Coastguard Worker 
1131*bbecb9d1SAndroid Build Coastguard Worker    switch (virgl_resource_export_fd(res, fd)) {
1132*bbecb9d1SAndroid Build Coastguard Worker    case VIRGL_RESOURCE_FD_DMABUF:
1133*bbecb9d1SAndroid Build Coastguard Worker       *fd_type = VIRGL_RENDERER_BLOB_FD_TYPE_DMABUF;
1134*bbecb9d1SAndroid Build Coastguard Worker       break;
1135*bbecb9d1SAndroid Build Coastguard Worker    case VIRGL_RESOURCE_FD_OPAQUE:
1136*bbecb9d1SAndroid Build Coastguard Worker       *fd_type = VIRGL_RENDERER_BLOB_FD_TYPE_OPAQUE;
1137*bbecb9d1SAndroid Build Coastguard Worker       break;
1138*bbecb9d1SAndroid Build Coastguard Worker    case VIRGL_RESOURCE_FD_SHM:
1139*bbecb9d1SAndroid Build Coastguard Worker       *fd_type = VIRGL_RENDERER_BLOB_FD_TYPE_SHM;
1140*bbecb9d1SAndroid Build Coastguard Worker       break;
1141*bbecb9d1SAndroid Build Coastguard Worker    default:
1142*bbecb9d1SAndroid Build Coastguard Worker       return EINVAL;
1143*bbecb9d1SAndroid Build Coastguard Worker    }
1144*bbecb9d1SAndroid Build Coastguard Worker 
1145*bbecb9d1SAndroid Build Coastguard Worker    return 0;
1146*bbecb9d1SAndroid Build Coastguard Worker }
1147*bbecb9d1SAndroid Build Coastguard Worker 
1148*bbecb9d1SAndroid Build Coastguard Worker int
virgl_renderer_resource_import_blob(const struct virgl_renderer_resource_import_blob_args * args)1149*bbecb9d1SAndroid Build Coastguard Worker virgl_renderer_resource_import_blob(const struct virgl_renderer_resource_import_blob_args *args)
1150*bbecb9d1SAndroid Build Coastguard Worker {
1151*bbecb9d1SAndroid Build Coastguard Worker    TRACE_FUNC();
1152*bbecb9d1SAndroid Build Coastguard Worker    struct virgl_resource *res;
1153*bbecb9d1SAndroid Build Coastguard Worker 
1154*bbecb9d1SAndroid Build Coastguard Worker    /* user resource id must be greater than 0 */
1155*bbecb9d1SAndroid Build Coastguard Worker    if (args->res_handle == 0)
1156*bbecb9d1SAndroid Build Coastguard Worker       return -EINVAL;
1157*bbecb9d1SAndroid Build Coastguard Worker 
1158*bbecb9d1SAndroid Build Coastguard Worker    /* user resource id must be unique */
1159*bbecb9d1SAndroid Build Coastguard Worker    if (virgl_resource_lookup(args->res_handle))
1160*bbecb9d1SAndroid Build Coastguard Worker       return -EINVAL;
1161*bbecb9d1SAndroid Build Coastguard Worker 
1162*bbecb9d1SAndroid Build Coastguard Worker    switch (args->blob_mem) {
1163*bbecb9d1SAndroid Build Coastguard Worker    case VIRGL_RENDERER_BLOB_MEM_HOST3D:
1164*bbecb9d1SAndroid Build Coastguard Worker    case VIRGL_RENDERER_BLOB_MEM_GUEST_VRAM:
1165*bbecb9d1SAndroid Build Coastguard Worker       break;
1166*bbecb9d1SAndroid Build Coastguard Worker    default:
1167*bbecb9d1SAndroid Build Coastguard Worker       return -EINVAL;
1168*bbecb9d1SAndroid Build Coastguard Worker    }
1169*bbecb9d1SAndroid Build Coastguard Worker 
1170*bbecb9d1SAndroid Build Coastguard Worker    enum virgl_resource_fd_type fd_type = VIRGL_RESOURCE_FD_INVALID;
1171*bbecb9d1SAndroid Build Coastguard Worker    switch (args->fd_type) {
1172*bbecb9d1SAndroid Build Coastguard Worker    case VIRGL_RENDERER_BLOB_FD_TYPE_DMABUF:
1173*bbecb9d1SAndroid Build Coastguard Worker       fd_type = VIRGL_RESOURCE_FD_DMABUF;
1174*bbecb9d1SAndroid Build Coastguard Worker       break;
1175*bbecb9d1SAndroid Build Coastguard Worker    case VIRGL_RENDERER_BLOB_FD_TYPE_OPAQUE:
1176*bbecb9d1SAndroid Build Coastguard Worker       fd_type = VIRGL_RESOURCE_FD_OPAQUE;
1177*bbecb9d1SAndroid Build Coastguard Worker       break;
1178*bbecb9d1SAndroid Build Coastguard Worker    case VIRGL_RENDERER_BLOB_FD_TYPE_SHM:
1179*bbecb9d1SAndroid Build Coastguard Worker       fd_type = VIRGL_RESOURCE_FD_SHM;
1180*bbecb9d1SAndroid Build Coastguard Worker       break;
1181*bbecb9d1SAndroid Build Coastguard Worker    default:
1182*bbecb9d1SAndroid Build Coastguard Worker       return -EINVAL;
1183*bbecb9d1SAndroid Build Coastguard Worker    }
1184*bbecb9d1SAndroid Build Coastguard Worker 
1185*bbecb9d1SAndroid Build Coastguard Worker    if (args->fd < 0)
1186*bbecb9d1SAndroid Build Coastguard Worker       return -EINVAL;
1187*bbecb9d1SAndroid Build Coastguard Worker    if (args->size == 0)
1188*bbecb9d1SAndroid Build Coastguard Worker       return -EINVAL;
1189*bbecb9d1SAndroid Build Coastguard Worker 
1190*bbecb9d1SAndroid Build Coastguard Worker    res = virgl_resource_create_from_fd(args->res_handle,
1191*bbecb9d1SAndroid Build Coastguard Worker                                        fd_type,
1192*bbecb9d1SAndroid Build Coastguard Worker                                        args->fd,
1193*bbecb9d1SAndroid Build Coastguard Worker                                        NULL,
1194*bbecb9d1SAndroid Build Coastguard Worker                                        0,
1195*bbecb9d1SAndroid Build Coastguard Worker                                        NULL);
1196*bbecb9d1SAndroid Build Coastguard Worker    if (!res)
1197*bbecb9d1SAndroid Build Coastguard Worker       return -ENOMEM;
1198*bbecb9d1SAndroid Build Coastguard Worker 
1199*bbecb9d1SAndroid Build Coastguard Worker    res->map_info = 0;
1200*bbecb9d1SAndroid Build Coastguard Worker    res->map_size = args->size;
1201*bbecb9d1SAndroid Build Coastguard Worker 
1202*bbecb9d1SAndroid Build Coastguard Worker    return 0;
1203*bbecb9d1SAndroid Build Coastguard Worker }
1204*bbecb9d1SAndroid Build Coastguard Worker 
1205*bbecb9d1SAndroid Build Coastguard Worker int
virgl_renderer_export_fence(uint32_t client_fence_id,int * fd)1206*bbecb9d1SAndroid Build Coastguard Worker virgl_renderer_export_fence(uint32_t client_fence_id, int *fd)
1207*bbecb9d1SAndroid Build Coastguard Worker {
1208*bbecb9d1SAndroid Build Coastguard Worker    TRACE_FUNC();
1209*bbecb9d1SAndroid Build Coastguard Worker    return vrend_renderer_export_ctx0_fence(client_fence_id, fd);
1210*bbecb9d1SAndroid Build Coastguard Worker }
1211