xref: /aosp_15_r20/external/virglrenderer/vtest/vtest_renderer.c (revision bbecb9d118dfdb95f99bd754f8fa9be01f189df3)
1*bbecb9d1SAndroid Build Coastguard Worker /**************************************************************************
2*bbecb9d1SAndroid Build Coastguard Worker  *
3*bbecb9d1SAndroid Build Coastguard Worker  * Copyright (C) 2015 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 #ifdef HAVE_CONFIG_H
26*bbecb9d1SAndroid Build Coastguard Worker #include "config.h"
27*bbecb9d1SAndroid Build Coastguard Worker #endif
28*bbecb9d1SAndroid Build Coastguard Worker 
29*bbecb9d1SAndroid Build Coastguard Worker #include <stdlib.h>
30*bbecb9d1SAndroid Build Coastguard Worker #include <stdio.h>
31*bbecb9d1SAndroid Build Coastguard Worker #include <string.h>
32*bbecb9d1SAndroid Build Coastguard Worker #include <time.h>
33*bbecb9d1SAndroid Build Coastguard Worker #include <unistd.h>
34*bbecb9d1SAndroid Build Coastguard Worker #include <fcntl.h>
35*bbecb9d1SAndroid Build Coastguard Worker #include <limits.h>
36*bbecb9d1SAndroid Build Coastguard Worker 
37*bbecb9d1SAndroid Build Coastguard Worker #include "virgl_hw.h"
38*bbecb9d1SAndroid Build Coastguard Worker #include "virglrenderer.h"
39*bbecb9d1SAndroid Build Coastguard Worker 
40*bbecb9d1SAndroid Build Coastguard Worker #include <sys/uio.h>
41*bbecb9d1SAndroid Build Coastguard Worker #include <sys/socket.h>
42*bbecb9d1SAndroid Build Coastguard Worker #include <sys/mman.h>
43*bbecb9d1SAndroid Build Coastguard Worker #ifdef HAVE_EVENTFD_H
44*bbecb9d1SAndroid Build Coastguard Worker #include <sys/eventfd.h>
45*bbecb9d1SAndroid Build Coastguard Worker #endif
46*bbecb9d1SAndroid Build Coastguard Worker 
47*bbecb9d1SAndroid Build Coastguard Worker #include "vtest.h"
48*bbecb9d1SAndroid Build Coastguard Worker #include "vtest_shm.h"
49*bbecb9d1SAndroid Build Coastguard Worker #include "vtest_protocol.h"
50*bbecb9d1SAndroid Build Coastguard Worker 
51*bbecb9d1SAndroid Build Coastguard Worker #include "util.h"
52*bbecb9d1SAndroid Build Coastguard Worker #include "util/u_debug.h"
53*bbecb9d1SAndroid Build Coastguard Worker #include "util/u_double_list.h"
54*bbecb9d1SAndroid Build Coastguard Worker #include "util/u_math.h"
55*bbecb9d1SAndroid Build Coastguard Worker #include "util/u_memory.h"
56*bbecb9d1SAndroid Build Coastguard Worker #include "util/u_pointer.h"
57*bbecb9d1SAndroid Build Coastguard Worker #include "util/u_hash_table.h"
58*bbecb9d1SAndroid Build Coastguard Worker 
59*bbecb9d1SAndroid Build Coastguard Worker #define VTEST_MAX_TIMELINE_COUNT 64
60*bbecb9d1SAndroid Build Coastguard Worker 
61*bbecb9d1SAndroid Build Coastguard Worker struct vtest_resource {
62*bbecb9d1SAndroid Build Coastguard Worker    struct list_head head;
63*bbecb9d1SAndroid Build Coastguard Worker 
64*bbecb9d1SAndroid Build Coastguard Worker    uint32_t server_res_id;
65*bbecb9d1SAndroid Build Coastguard Worker    uint32_t res_id;
66*bbecb9d1SAndroid Build Coastguard Worker 
67*bbecb9d1SAndroid Build Coastguard Worker    struct iovec iov;
68*bbecb9d1SAndroid Build Coastguard Worker };
69*bbecb9d1SAndroid Build Coastguard Worker 
70*bbecb9d1SAndroid Build Coastguard Worker struct vtest_sync {
71*bbecb9d1SAndroid Build Coastguard Worker    struct list_head head;
72*bbecb9d1SAndroid Build Coastguard Worker 
73*bbecb9d1SAndroid Build Coastguard Worker    int sync_id;
74*bbecb9d1SAndroid Build Coastguard Worker    int refcount;
75*bbecb9d1SAndroid Build Coastguard Worker 
76*bbecb9d1SAndroid Build Coastguard Worker    uint64_t value;
77*bbecb9d1SAndroid Build Coastguard Worker };
78*bbecb9d1SAndroid Build Coastguard Worker 
79*bbecb9d1SAndroid Build Coastguard Worker struct vtest_timeline {
80*bbecb9d1SAndroid Build Coastguard Worker    struct list_head submits;
81*bbecb9d1SAndroid Build Coastguard Worker };
82*bbecb9d1SAndroid Build Coastguard Worker 
83*bbecb9d1SAndroid Build Coastguard Worker struct vtest_timeline_submit {
84*bbecb9d1SAndroid Build Coastguard Worker    struct list_head head;
85*bbecb9d1SAndroid Build Coastguard Worker 
86*bbecb9d1SAndroid Build Coastguard Worker    struct vtest_timeline *timeline;
87*bbecb9d1SAndroid Build Coastguard Worker 
88*bbecb9d1SAndroid Build Coastguard Worker    uint32_t count;
89*bbecb9d1SAndroid Build Coastguard Worker    struct vtest_sync **syncs;
90*bbecb9d1SAndroid Build Coastguard Worker    uint64_t *values;
91*bbecb9d1SAndroid Build Coastguard Worker };
92*bbecb9d1SAndroid Build Coastguard Worker 
93*bbecb9d1SAndroid Build Coastguard Worker struct vtest_sync_wait {
94*bbecb9d1SAndroid Build Coastguard Worker    struct list_head head;
95*bbecb9d1SAndroid Build Coastguard Worker 
96*bbecb9d1SAndroid Build Coastguard Worker    int fd;
97*bbecb9d1SAndroid Build Coastguard Worker 
98*bbecb9d1SAndroid Build Coastguard Worker    uint32_t flags;
99*bbecb9d1SAndroid Build Coastguard Worker    uint64_t valid_before;
100*bbecb9d1SAndroid Build Coastguard Worker 
101*bbecb9d1SAndroid Build Coastguard Worker    uint32_t count;
102*bbecb9d1SAndroid Build Coastguard Worker    struct vtest_sync **syncs;
103*bbecb9d1SAndroid Build Coastguard Worker    uint64_t *values;
104*bbecb9d1SAndroid Build Coastguard Worker 
105*bbecb9d1SAndroid Build Coastguard Worker    uint32_t signaled_count;
106*bbecb9d1SAndroid Build Coastguard Worker };
107*bbecb9d1SAndroid Build Coastguard Worker 
108*bbecb9d1SAndroid Build Coastguard Worker struct vtest_context {
109*bbecb9d1SAndroid Build Coastguard Worker    struct list_head head;
110*bbecb9d1SAndroid Build Coastguard Worker 
111*bbecb9d1SAndroid Build Coastguard Worker    int ctx_id;
112*bbecb9d1SAndroid Build Coastguard Worker 
113*bbecb9d1SAndroid Build Coastguard Worker    struct vtest_input *input;
114*bbecb9d1SAndroid Build Coastguard Worker    int out_fd;
115*bbecb9d1SAndroid Build Coastguard Worker 
116*bbecb9d1SAndroid Build Coastguard Worker    char *debug_name;
117*bbecb9d1SAndroid Build Coastguard Worker 
118*bbecb9d1SAndroid Build Coastguard Worker    unsigned protocol_version;
119*bbecb9d1SAndroid Build Coastguard Worker    unsigned capset_id;
120*bbecb9d1SAndroid Build Coastguard Worker    bool context_initialized;
121*bbecb9d1SAndroid Build Coastguard Worker 
122*bbecb9d1SAndroid Build Coastguard Worker    struct util_hash_table *resource_table;
123*bbecb9d1SAndroid Build Coastguard Worker    struct util_hash_table *sync_table;
124*bbecb9d1SAndroid Build Coastguard Worker 
125*bbecb9d1SAndroid Build Coastguard Worker    struct vtest_timeline timelines[VTEST_MAX_TIMELINE_COUNT];
126*bbecb9d1SAndroid Build Coastguard Worker 
127*bbecb9d1SAndroid Build Coastguard Worker    struct list_head sync_waits;
128*bbecb9d1SAndroid Build Coastguard Worker };
129*bbecb9d1SAndroid Build Coastguard Worker 
130*bbecb9d1SAndroid Build Coastguard Worker struct vtest_renderer {
131*bbecb9d1SAndroid Build Coastguard Worker    const char *rendernode_name;
132*bbecb9d1SAndroid Build Coastguard Worker    bool multi_clients;
133*bbecb9d1SAndroid Build Coastguard Worker    uint32_t ctx_flags;
134*bbecb9d1SAndroid Build Coastguard Worker 
135*bbecb9d1SAndroid Build Coastguard Worker    uint32_t max_length;
136*bbecb9d1SAndroid Build Coastguard Worker 
137*bbecb9d1SAndroid Build Coastguard Worker    int implicit_fence_submitted;
138*bbecb9d1SAndroid Build Coastguard Worker    int implicit_fence_completed;
139*bbecb9d1SAndroid Build Coastguard Worker 
140*bbecb9d1SAndroid Build Coastguard Worker    struct list_head active_contexts;
141*bbecb9d1SAndroid Build Coastguard Worker    struct list_head free_contexts;
142*bbecb9d1SAndroid Build Coastguard Worker    int next_context_id;
143*bbecb9d1SAndroid Build Coastguard Worker 
144*bbecb9d1SAndroid Build Coastguard Worker    struct list_head free_resources;
145*bbecb9d1SAndroid Build Coastguard Worker    int next_resource_id;
146*bbecb9d1SAndroid Build Coastguard Worker 
147*bbecb9d1SAndroid Build Coastguard Worker    struct list_head free_syncs;
148*bbecb9d1SAndroid Build Coastguard Worker    int next_sync_id;
149*bbecb9d1SAndroid Build Coastguard Worker 
150*bbecb9d1SAndroid Build Coastguard Worker    struct vtest_context *current_context;
151*bbecb9d1SAndroid Build Coastguard Worker };
152*bbecb9d1SAndroid Build Coastguard Worker 
153*bbecb9d1SAndroid Build Coastguard Worker /*
154*bbecb9d1SAndroid Build Coastguard Worker  * VCMD_RESOURCE_BUSY_WAIT is used to wait GPU works (VCMD_SUBMIT_CMD) or CPU
155*bbecb9d1SAndroid Build Coastguard Worker  * works (VCMD_TRANSFER_GET2).  A fence is needed only for GPU works.
156*bbecb9d1SAndroid Build Coastguard Worker  */
vtest_create_implicit_fence(struct vtest_renderer * renderer)157*bbecb9d1SAndroid Build Coastguard Worker static void vtest_create_implicit_fence(struct vtest_renderer *renderer)
158*bbecb9d1SAndroid Build Coastguard Worker {
159*bbecb9d1SAndroid Build Coastguard Worker    virgl_renderer_create_fence(++renderer->implicit_fence_submitted, 0);
160*bbecb9d1SAndroid Build Coastguard Worker }
161*bbecb9d1SAndroid Build Coastguard Worker 
vtest_write_implicit_fence(UNUSED void * cookie,uint32_t fence_id_in)162*bbecb9d1SAndroid Build Coastguard Worker static void vtest_write_implicit_fence(UNUSED void *cookie, uint32_t fence_id_in)
163*bbecb9d1SAndroid Build Coastguard Worker {
164*bbecb9d1SAndroid Build Coastguard Worker    struct vtest_renderer *renderer = (struct vtest_renderer*)cookie;
165*bbecb9d1SAndroid Build Coastguard Worker    renderer->implicit_fence_completed = fence_id_in;
166*bbecb9d1SAndroid Build Coastguard Worker }
167*bbecb9d1SAndroid Build Coastguard Worker 
168*bbecb9d1SAndroid Build Coastguard Worker static void vtest_signal_timeline(struct vtest_timeline *timeline,
169*bbecb9d1SAndroid Build Coastguard Worker                                   struct vtest_timeline_submit *to_submit);
170*bbecb9d1SAndroid Build Coastguard Worker 
vtest_write_context_fence(UNUSED void * cookie,UNUSED uint32_t ctx_id,UNUSED uint32_t ring_idx,uint64_t fence_id)171*bbecb9d1SAndroid Build Coastguard Worker static void vtest_write_context_fence(UNUSED void *cookie,
172*bbecb9d1SAndroid Build Coastguard Worker                                       UNUSED uint32_t ctx_id,
173*bbecb9d1SAndroid Build Coastguard Worker                                       UNUSED uint32_t ring_idx,
174*bbecb9d1SAndroid Build Coastguard Worker                                       uint64_t fence_id)
175*bbecb9d1SAndroid Build Coastguard Worker {
176*bbecb9d1SAndroid Build Coastguard Worker    struct vtest_timeline_submit *submit = (void*)(uintptr_t)fence_id;
177*bbecb9d1SAndroid Build Coastguard Worker    vtest_signal_timeline(submit->timeline, submit);
178*bbecb9d1SAndroid Build Coastguard Worker }
179*bbecb9d1SAndroid Build Coastguard Worker 
vtest_get_drm_fd(void * cookie)180*bbecb9d1SAndroid Build Coastguard Worker static int vtest_get_drm_fd(void *cookie)
181*bbecb9d1SAndroid Build Coastguard Worker {
182*bbecb9d1SAndroid Build Coastguard Worker    int fd = -1;
183*bbecb9d1SAndroid Build Coastguard Worker    struct vtest_renderer *renderer = (struct vtest_renderer*)cookie;
184*bbecb9d1SAndroid Build Coastguard Worker    if (!renderer->rendernode_name)
185*bbecb9d1SAndroid Build Coastguard Worker       return -1;
186*bbecb9d1SAndroid Build Coastguard Worker    fd = open(renderer->rendernode_name, O_RDWR | O_CLOEXEC | O_NOCTTY | O_NONBLOCK);
187*bbecb9d1SAndroid Build Coastguard Worker    if (fd == -1)
188*bbecb9d1SAndroid Build Coastguard Worker       fprintf(stderr, "Unable to open rendernode '%s' falling back to default search\n",
189*bbecb9d1SAndroid Build Coastguard Worker               renderer->rendernode_name);
190*bbecb9d1SAndroid Build Coastguard Worker    return fd;
191*bbecb9d1SAndroid Build Coastguard Worker }
192*bbecb9d1SAndroid Build Coastguard Worker 
193*bbecb9d1SAndroid Build Coastguard Worker static struct virgl_renderer_callbacks renderer_cbs = {
194*bbecb9d1SAndroid Build Coastguard Worker    .version = VIRGL_RENDERER_CALLBACKS_VERSION,
195*bbecb9d1SAndroid Build Coastguard Worker    .write_fence = vtest_write_implicit_fence,
196*bbecb9d1SAndroid Build Coastguard Worker    .get_drm_fd = vtest_get_drm_fd,
197*bbecb9d1SAndroid Build Coastguard Worker    .write_context_fence = vtest_write_context_fence,
198*bbecb9d1SAndroid Build Coastguard Worker };
199*bbecb9d1SAndroid Build Coastguard Worker 
200*bbecb9d1SAndroid Build Coastguard Worker 
201*bbecb9d1SAndroid Build Coastguard Worker static struct vtest_renderer renderer = {
202*bbecb9d1SAndroid Build Coastguard Worker    .max_length = UINT_MAX,
203*bbecb9d1SAndroid Build Coastguard Worker    .next_context_id = 1,
204*bbecb9d1SAndroid Build Coastguard Worker    .next_resource_id = 1,
205*bbecb9d1SAndroid Build Coastguard Worker    .next_sync_id = 1,
206*bbecb9d1SAndroid Build Coastguard Worker };
207*bbecb9d1SAndroid Build Coastguard Worker 
vtest_new_resource(uint32_t client_res_id)208*bbecb9d1SAndroid Build Coastguard Worker static struct vtest_resource *vtest_new_resource(uint32_t client_res_id)
209*bbecb9d1SAndroid Build Coastguard Worker {
210*bbecb9d1SAndroid Build Coastguard Worker    struct vtest_resource *res;
211*bbecb9d1SAndroid Build Coastguard Worker 
212*bbecb9d1SAndroid Build Coastguard Worker    if (LIST_IS_EMPTY(&renderer.free_resources)) {
213*bbecb9d1SAndroid Build Coastguard Worker       res = malloc(sizeof(*res));
214*bbecb9d1SAndroid Build Coastguard Worker       if (!res) {
215*bbecb9d1SAndroid Build Coastguard Worker          return NULL;
216*bbecb9d1SAndroid Build Coastguard Worker       }
217*bbecb9d1SAndroid Build Coastguard Worker 
218*bbecb9d1SAndroid Build Coastguard Worker       res->server_res_id = renderer.next_resource_id++;
219*bbecb9d1SAndroid Build Coastguard Worker    } else {
220*bbecb9d1SAndroid Build Coastguard Worker       res = LIST_ENTRY(struct vtest_resource, renderer.free_resources.next, head);
221*bbecb9d1SAndroid Build Coastguard Worker       list_del(&res->head);
222*bbecb9d1SAndroid Build Coastguard Worker    }
223*bbecb9d1SAndroid Build Coastguard Worker 
224*bbecb9d1SAndroid Build Coastguard Worker    res->res_id = client_res_id ? client_res_id : res->server_res_id;
225*bbecb9d1SAndroid Build Coastguard Worker    res->iov.iov_base = NULL;
226*bbecb9d1SAndroid Build Coastguard Worker    res->iov.iov_len = 0;
227*bbecb9d1SAndroid Build Coastguard Worker 
228*bbecb9d1SAndroid Build Coastguard Worker    return res;
229*bbecb9d1SAndroid Build Coastguard Worker }
230*bbecb9d1SAndroid Build Coastguard Worker 
vtest_unref_resource(struct vtest_resource * res)231*bbecb9d1SAndroid Build Coastguard Worker static void vtest_unref_resource(struct vtest_resource *res)
232*bbecb9d1SAndroid Build Coastguard Worker {
233*bbecb9d1SAndroid Build Coastguard Worker    /* virgl_renderer_ctx_detach_resource and virgl_renderer_resource_detach_iov
234*bbecb9d1SAndroid Build Coastguard Worker     * are implied
235*bbecb9d1SAndroid Build Coastguard Worker     */
236*bbecb9d1SAndroid Build Coastguard Worker    virgl_renderer_resource_unref(res->res_id);
237*bbecb9d1SAndroid Build Coastguard Worker 
238*bbecb9d1SAndroid Build Coastguard Worker    if (res->iov.iov_base)
239*bbecb9d1SAndroid Build Coastguard Worker       munmap(res->iov.iov_base, res->iov.iov_len);
240*bbecb9d1SAndroid Build Coastguard Worker 
241*bbecb9d1SAndroid Build Coastguard Worker    list_add(&res->head, &renderer.free_resources);
242*bbecb9d1SAndroid Build Coastguard Worker }
243*bbecb9d1SAndroid Build Coastguard Worker 
vtest_new_sync(uint64_t value)244*bbecb9d1SAndroid Build Coastguard Worker static struct vtest_sync *vtest_new_sync(uint64_t value)
245*bbecb9d1SAndroid Build Coastguard Worker {
246*bbecb9d1SAndroid Build Coastguard Worker    struct vtest_sync *sync;
247*bbecb9d1SAndroid Build Coastguard Worker 
248*bbecb9d1SAndroid Build Coastguard Worker    if (LIST_IS_EMPTY(&renderer.free_syncs)) {
249*bbecb9d1SAndroid Build Coastguard Worker       sync = malloc(sizeof(*sync));
250*bbecb9d1SAndroid Build Coastguard Worker       if (!sync) {
251*bbecb9d1SAndroid Build Coastguard Worker          return NULL;
252*bbecb9d1SAndroid Build Coastguard Worker       }
253*bbecb9d1SAndroid Build Coastguard Worker 
254*bbecb9d1SAndroid Build Coastguard Worker       sync->sync_id = renderer.next_sync_id++;
255*bbecb9d1SAndroid Build Coastguard Worker    } else {
256*bbecb9d1SAndroid Build Coastguard Worker       sync = LIST_ENTRY(struct vtest_sync, renderer.free_syncs.next, head);
257*bbecb9d1SAndroid Build Coastguard Worker       list_del(&sync->head);
258*bbecb9d1SAndroid Build Coastguard Worker    }
259*bbecb9d1SAndroid Build Coastguard Worker 
260*bbecb9d1SAndroid Build Coastguard Worker    sync->refcount = 1;
261*bbecb9d1SAndroid Build Coastguard Worker    sync->value = value;
262*bbecb9d1SAndroid Build Coastguard Worker 
263*bbecb9d1SAndroid Build Coastguard Worker    return sync;
264*bbecb9d1SAndroid Build Coastguard Worker }
265*bbecb9d1SAndroid Build Coastguard Worker 
vtest_ref_sync(struct vtest_sync * sync)266*bbecb9d1SAndroid Build Coastguard Worker static struct vtest_sync *vtest_ref_sync(struct vtest_sync *sync)
267*bbecb9d1SAndroid Build Coastguard Worker {
268*bbecb9d1SAndroid Build Coastguard Worker    sync->refcount++;
269*bbecb9d1SAndroid Build Coastguard Worker    return sync;
270*bbecb9d1SAndroid Build Coastguard Worker }
271*bbecb9d1SAndroid Build Coastguard Worker 
vtest_unref_sync(struct vtest_sync * sync)272*bbecb9d1SAndroid Build Coastguard Worker static void vtest_unref_sync(struct vtest_sync *sync)
273*bbecb9d1SAndroid Build Coastguard Worker {
274*bbecb9d1SAndroid Build Coastguard Worker    assert(sync->refcount);
275*bbecb9d1SAndroid Build Coastguard Worker    sync->refcount--;
276*bbecb9d1SAndroid Build Coastguard Worker    if (sync->refcount)
277*bbecb9d1SAndroid Build Coastguard Worker       return;
278*bbecb9d1SAndroid Build Coastguard Worker 
279*bbecb9d1SAndroid Build Coastguard Worker    list_add(&sync->head, &renderer.free_syncs);
280*bbecb9d1SAndroid Build Coastguard Worker }
281*bbecb9d1SAndroid Build Coastguard Worker 
vtest_free_timeline_submit(struct vtest_timeline_submit * submit)282*bbecb9d1SAndroid Build Coastguard Worker static void vtest_free_timeline_submit(struct vtest_timeline_submit *submit)
283*bbecb9d1SAndroid Build Coastguard Worker {
284*bbecb9d1SAndroid Build Coastguard Worker    uint32_t i;
285*bbecb9d1SAndroid Build Coastguard Worker    for (i = 0; i < submit->count; i++)
286*bbecb9d1SAndroid Build Coastguard Worker       vtest_unref_sync(submit->syncs[i]);
287*bbecb9d1SAndroid Build Coastguard Worker    free(submit);
288*bbecb9d1SAndroid Build Coastguard Worker }
289*bbecb9d1SAndroid Build Coastguard Worker 
vtest_free_sync_wait(struct vtest_sync_wait * wait)290*bbecb9d1SAndroid Build Coastguard Worker static void vtest_free_sync_wait(struct vtest_sync_wait *wait)
291*bbecb9d1SAndroid Build Coastguard Worker {
292*bbecb9d1SAndroid Build Coastguard Worker    uint32_t i;
293*bbecb9d1SAndroid Build Coastguard Worker 
294*bbecb9d1SAndroid Build Coastguard Worker    for (i = 0; i < wait->count; i++) {
295*bbecb9d1SAndroid Build Coastguard Worker       if (wait->syncs[i])
296*bbecb9d1SAndroid Build Coastguard Worker          vtest_unref_sync(wait->syncs[i]);
297*bbecb9d1SAndroid Build Coastguard Worker    }
298*bbecb9d1SAndroid Build Coastguard Worker    close(wait->fd);
299*bbecb9d1SAndroid Build Coastguard Worker    free(wait);
300*bbecb9d1SAndroid Build Coastguard Worker }
301*bbecb9d1SAndroid Build Coastguard Worker 
302*bbecb9d1SAndroid Build Coastguard Worker static uint32_t
u32_hash_func(const void * key)303*bbecb9d1SAndroid Build Coastguard Worker u32_hash_func(const void *key)
304*bbecb9d1SAndroid Build Coastguard Worker {
305*bbecb9d1SAndroid Build Coastguard Worker    intptr_t ip = pointer_to_intptr(key);
306*bbecb9d1SAndroid Build Coastguard Worker    return (uint32_t)(ip & 0xffffffff);
307*bbecb9d1SAndroid Build Coastguard Worker }
308*bbecb9d1SAndroid Build Coastguard Worker 
309*bbecb9d1SAndroid Build Coastguard Worker static bool
u32_equal_func(const void * key1,const void * key2)310*bbecb9d1SAndroid Build Coastguard Worker u32_equal_func(const void *key1, const void *key2)
311*bbecb9d1SAndroid Build Coastguard Worker {
312*bbecb9d1SAndroid Build Coastguard Worker    return key1 == key2;
313*bbecb9d1SAndroid Build Coastguard Worker }
314*bbecb9d1SAndroid Build Coastguard Worker 
315*bbecb9d1SAndroid Build Coastguard Worker static void
resource_destroy_func(void * value)316*bbecb9d1SAndroid Build Coastguard Worker resource_destroy_func(void *value)
317*bbecb9d1SAndroid Build Coastguard Worker {
318*bbecb9d1SAndroid Build Coastguard Worker    struct vtest_resource *res = value;
319*bbecb9d1SAndroid Build Coastguard Worker    vtest_unref_resource(res);
320*bbecb9d1SAndroid Build Coastguard Worker }
321*bbecb9d1SAndroid Build Coastguard Worker 
322*bbecb9d1SAndroid Build Coastguard Worker static void
sync_destroy_func(void * value)323*bbecb9d1SAndroid Build Coastguard Worker sync_destroy_func(void *value)
324*bbecb9d1SAndroid Build Coastguard Worker {
325*bbecb9d1SAndroid Build Coastguard Worker    struct vtest_sync *sync = value;
326*bbecb9d1SAndroid Build Coastguard Worker    vtest_unref_sync(sync);
327*bbecb9d1SAndroid Build Coastguard Worker }
328*bbecb9d1SAndroid Build Coastguard Worker 
vtest_block_write(int fd,void * buf,int size)329*bbecb9d1SAndroid Build Coastguard Worker static int vtest_block_write(int fd, void *buf, int size)
330*bbecb9d1SAndroid Build Coastguard Worker {
331*bbecb9d1SAndroid Build Coastguard Worker    char *ptr = buf;
332*bbecb9d1SAndroid Build Coastguard Worker    int left;
333*bbecb9d1SAndroid Build Coastguard Worker    int ret;
334*bbecb9d1SAndroid Build Coastguard Worker    left = size;
335*bbecb9d1SAndroid Build Coastguard Worker 
336*bbecb9d1SAndroid Build Coastguard Worker    do {
337*bbecb9d1SAndroid Build Coastguard Worker       ret = write(fd, ptr, left);
338*bbecb9d1SAndroid Build Coastguard Worker       if (ret < 0) {
339*bbecb9d1SAndroid Build Coastguard Worker          return -errno;
340*bbecb9d1SAndroid Build Coastguard Worker       }
341*bbecb9d1SAndroid Build Coastguard Worker 
342*bbecb9d1SAndroid Build Coastguard Worker       left -= ret;
343*bbecb9d1SAndroid Build Coastguard Worker       ptr += ret;
344*bbecb9d1SAndroid Build Coastguard Worker    } while (left);
345*bbecb9d1SAndroid Build Coastguard Worker 
346*bbecb9d1SAndroid Build Coastguard Worker    return size;
347*bbecb9d1SAndroid Build Coastguard Worker }
348*bbecb9d1SAndroid Build Coastguard Worker 
vtest_block_read(struct vtest_input * input,void * buf,int size)349*bbecb9d1SAndroid Build Coastguard Worker int vtest_block_read(struct vtest_input *input, void *buf, int size)
350*bbecb9d1SAndroid Build Coastguard Worker {
351*bbecb9d1SAndroid Build Coastguard Worker    int fd = input->data.fd;
352*bbecb9d1SAndroid Build Coastguard Worker    char *ptr = buf;
353*bbecb9d1SAndroid Build Coastguard Worker    int left;
354*bbecb9d1SAndroid Build Coastguard Worker    int ret;
355*bbecb9d1SAndroid Build Coastguard Worker    static int savefd = -1;
356*bbecb9d1SAndroid Build Coastguard Worker 
357*bbecb9d1SAndroid Build Coastguard Worker    left = size;
358*bbecb9d1SAndroid Build Coastguard Worker    do {
359*bbecb9d1SAndroid Build Coastguard Worker       ret = read(fd, ptr, left);
360*bbecb9d1SAndroid Build Coastguard Worker       if (ret <= 0) {
361*bbecb9d1SAndroid Build Coastguard Worker          return ret == -1 ? -errno : 0;
362*bbecb9d1SAndroid Build Coastguard Worker       }
363*bbecb9d1SAndroid Build Coastguard Worker 
364*bbecb9d1SAndroid Build Coastguard Worker       left -= ret;
365*bbecb9d1SAndroid Build Coastguard Worker       ptr += ret;
366*bbecb9d1SAndroid Build Coastguard Worker    } while (left);
367*bbecb9d1SAndroid Build Coastguard Worker 
368*bbecb9d1SAndroid Build Coastguard Worker    if (getenv("VTEST_SAVE")) {
369*bbecb9d1SAndroid Build Coastguard Worker       if (savefd == -1) {
370*bbecb9d1SAndroid Build Coastguard Worker          savefd = open(getenv("VTEST_SAVE"),
371*bbecb9d1SAndroid Build Coastguard Worker                        O_CLOEXEC|O_CREAT|O_WRONLY|O_TRUNC|O_DSYNC, S_IRUSR|S_IWUSR);
372*bbecb9d1SAndroid Build Coastguard Worker          if (savefd == -1) {
373*bbecb9d1SAndroid Build Coastguard Worker             perror("error opening save file");
374*bbecb9d1SAndroid Build Coastguard Worker             exit(1);
375*bbecb9d1SAndroid Build Coastguard Worker          }
376*bbecb9d1SAndroid Build Coastguard Worker       }
377*bbecb9d1SAndroid Build Coastguard Worker       if (write(savefd, buf, size) != size) {
378*bbecb9d1SAndroid Build Coastguard Worker          perror("failed to save");
379*bbecb9d1SAndroid Build Coastguard Worker          exit(1);
380*bbecb9d1SAndroid Build Coastguard Worker       }
381*bbecb9d1SAndroid Build Coastguard Worker    }
382*bbecb9d1SAndroid Build Coastguard Worker 
383*bbecb9d1SAndroid Build Coastguard Worker    return size;
384*bbecb9d1SAndroid Build Coastguard Worker }
385*bbecb9d1SAndroid Build Coastguard Worker 
vtest_send_fd(int socket_fd,int fd)386*bbecb9d1SAndroid Build Coastguard Worker static int vtest_send_fd(int socket_fd, int fd)
387*bbecb9d1SAndroid Build Coastguard Worker {
388*bbecb9d1SAndroid Build Coastguard Worker     struct iovec iovec;
389*bbecb9d1SAndroid Build Coastguard Worker     char buf[CMSG_SPACE(sizeof(int))];
390*bbecb9d1SAndroid Build Coastguard Worker     char c = 0;
391*bbecb9d1SAndroid Build Coastguard Worker     struct msghdr msgh = { 0 };
392*bbecb9d1SAndroid Build Coastguard Worker     memset(buf, 0, sizeof(buf));
393*bbecb9d1SAndroid Build Coastguard Worker 
394*bbecb9d1SAndroid Build Coastguard Worker     iovec.iov_base = &c;
395*bbecb9d1SAndroid Build Coastguard Worker     iovec.iov_len = sizeof(char);
396*bbecb9d1SAndroid Build Coastguard Worker 
397*bbecb9d1SAndroid Build Coastguard Worker     msgh.msg_name = NULL;
398*bbecb9d1SAndroid Build Coastguard Worker     msgh.msg_namelen = 0;
399*bbecb9d1SAndroid Build Coastguard Worker     msgh.msg_iov = &iovec;
400*bbecb9d1SAndroid Build Coastguard Worker     msgh.msg_iovlen = 1;
401*bbecb9d1SAndroid Build Coastguard Worker     msgh.msg_control = buf;
402*bbecb9d1SAndroid Build Coastguard Worker     msgh.msg_controllen = sizeof(buf);
403*bbecb9d1SAndroid Build Coastguard Worker     msgh.msg_flags = 0;
404*bbecb9d1SAndroid Build Coastguard Worker 
405*bbecb9d1SAndroid Build Coastguard Worker     struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msgh);
406*bbecb9d1SAndroid Build Coastguard Worker     cmsg->cmsg_level = SOL_SOCKET;
407*bbecb9d1SAndroid Build Coastguard Worker     cmsg->cmsg_type = SCM_RIGHTS;
408*bbecb9d1SAndroid Build Coastguard Worker     cmsg->cmsg_len = CMSG_LEN(sizeof(int));
409*bbecb9d1SAndroid Build Coastguard Worker 
410*bbecb9d1SAndroid Build Coastguard Worker     *((int *) CMSG_DATA(cmsg)) = fd;
411*bbecb9d1SAndroid Build Coastguard Worker 
412*bbecb9d1SAndroid Build Coastguard Worker     int size = sendmsg(socket_fd, &msgh, 0);
413*bbecb9d1SAndroid Build Coastguard Worker     if (size < 0) {
414*bbecb9d1SAndroid Build Coastguard Worker       return report_failure("Failed to send fd", -EINVAL);
415*bbecb9d1SAndroid Build Coastguard Worker     }
416*bbecb9d1SAndroid Build Coastguard Worker 
417*bbecb9d1SAndroid Build Coastguard Worker     return 0;
418*bbecb9d1SAndroid Build Coastguard Worker }
419*bbecb9d1SAndroid Build Coastguard Worker 
vtest_buf_read(struct vtest_input * input,void * buf,int size)420*bbecb9d1SAndroid Build Coastguard Worker int vtest_buf_read(struct vtest_input *input, void *buf, int size)
421*bbecb9d1SAndroid Build Coastguard Worker {
422*bbecb9d1SAndroid Build Coastguard Worker    struct vtest_buffer *inbuf = input->data.buffer;
423*bbecb9d1SAndroid Build Coastguard Worker    if (size > inbuf->size) {
424*bbecb9d1SAndroid Build Coastguard Worker       return 0;
425*bbecb9d1SAndroid Build Coastguard Worker    }
426*bbecb9d1SAndroid Build Coastguard Worker 
427*bbecb9d1SAndroid Build Coastguard Worker    memcpy(buf, inbuf->buffer, size);
428*bbecb9d1SAndroid Build Coastguard Worker    inbuf->buffer += size;
429*bbecb9d1SAndroid Build Coastguard Worker    inbuf->size -= size;
430*bbecb9d1SAndroid Build Coastguard Worker 
431*bbecb9d1SAndroid Build Coastguard Worker    return size;
432*bbecb9d1SAndroid Build Coastguard Worker }
433*bbecb9d1SAndroid Build Coastguard Worker 
vtest_init_renderer(bool multi_clients,int ctx_flags,const char * render_device)434*bbecb9d1SAndroid Build Coastguard Worker int vtest_init_renderer(bool multi_clients,
435*bbecb9d1SAndroid Build Coastguard Worker                         int ctx_flags,
436*bbecb9d1SAndroid Build Coastguard Worker                         const char *render_device)
437*bbecb9d1SAndroid Build Coastguard Worker {
438*bbecb9d1SAndroid Build Coastguard Worker    int ret;
439*bbecb9d1SAndroid Build Coastguard Worker 
440*bbecb9d1SAndroid Build Coastguard Worker    renderer.rendernode_name = render_device;
441*bbecb9d1SAndroid Build Coastguard Worker    list_inithead(&renderer.active_contexts);
442*bbecb9d1SAndroid Build Coastguard Worker    list_inithead(&renderer.free_contexts);
443*bbecb9d1SAndroid Build Coastguard Worker    list_inithead(&renderer.free_resources);
444*bbecb9d1SAndroid Build Coastguard Worker    list_inithead(&renderer.free_syncs);
445*bbecb9d1SAndroid Build Coastguard Worker 
446*bbecb9d1SAndroid Build Coastguard Worker    ctx_flags |= VIRGL_RENDERER_THREAD_SYNC |
447*bbecb9d1SAndroid Build Coastguard Worker                 VIRGL_RENDERER_USE_EXTERNAL_BLOB;
448*bbecb9d1SAndroid Build Coastguard Worker    ret = virgl_renderer_init(&renderer, ctx_flags, &renderer_cbs);
449*bbecb9d1SAndroid Build Coastguard Worker    if (ret) {
450*bbecb9d1SAndroid Build Coastguard Worker       fprintf(stderr, "failed to initialise renderer.\n");
451*bbecb9d1SAndroid Build Coastguard Worker       return -1;
452*bbecb9d1SAndroid Build Coastguard Worker    }
453*bbecb9d1SAndroid Build Coastguard Worker 
454*bbecb9d1SAndroid Build Coastguard Worker    renderer.multi_clients = multi_clients;
455*bbecb9d1SAndroid Build Coastguard Worker    renderer.ctx_flags = ctx_flags;
456*bbecb9d1SAndroid Build Coastguard Worker 
457*bbecb9d1SAndroid Build Coastguard Worker    return 0;
458*bbecb9d1SAndroid Build Coastguard Worker }
459*bbecb9d1SAndroid Build Coastguard Worker 
460*bbecb9d1SAndroid Build Coastguard Worker static void vtest_free_context(struct vtest_context *ctx, bool cleanup);
461*bbecb9d1SAndroid Build Coastguard Worker 
vtest_cleanup_renderer(void)462*bbecb9d1SAndroid Build Coastguard Worker void vtest_cleanup_renderer(void)
463*bbecb9d1SAndroid Build Coastguard Worker {
464*bbecb9d1SAndroid Build Coastguard Worker    if (renderer.next_context_id > 1) {
465*bbecb9d1SAndroid Build Coastguard Worker       struct vtest_context *ctx, *tmp;
466*bbecb9d1SAndroid Build Coastguard Worker 
467*bbecb9d1SAndroid Build Coastguard Worker       LIST_FOR_EACH_ENTRY_SAFE(ctx, tmp, &renderer.active_contexts, head) {
468*bbecb9d1SAndroid Build Coastguard Worker          vtest_destroy_context(ctx);
469*bbecb9d1SAndroid Build Coastguard Worker       }
470*bbecb9d1SAndroid Build Coastguard Worker       LIST_FOR_EACH_ENTRY_SAFE(ctx, tmp, &renderer.free_contexts, head) {
471*bbecb9d1SAndroid Build Coastguard Worker          vtest_free_context(ctx, true);
472*bbecb9d1SAndroid Build Coastguard Worker       }
473*bbecb9d1SAndroid Build Coastguard Worker       list_inithead(&renderer.active_contexts);
474*bbecb9d1SAndroid Build Coastguard Worker       list_inithead(&renderer.free_contexts);
475*bbecb9d1SAndroid Build Coastguard Worker 
476*bbecb9d1SAndroid Build Coastguard Worker       renderer.next_context_id = 1;
477*bbecb9d1SAndroid Build Coastguard Worker       renderer.current_context = NULL;
478*bbecb9d1SAndroid Build Coastguard Worker    }
479*bbecb9d1SAndroid Build Coastguard Worker 
480*bbecb9d1SAndroid Build Coastguard Worker    if (renderer.next_resource_id > 1) {
481*bbecb9d1SAndroid Build Coastguard Worker       struct vtest_resource *res, *tmp;
482*bbecb9d1SAndroid Build Coastguard Worker 
483*bbecb9d1SAndroid Build Coastguard Worker       LIST_FOR_EACH_ENTRY_SAFE(res, tmp, &renderer.free_resources, head) {
484*bbecb9d1SAndroid Build Coastguard Worker          free(res);
485*bbecb9d1SAndroid Build Coastguard Worker       }
486*bbecb9d1SAndroid Build Coastguard Worker       list_inithead(&renderer.free_resources);
487*bbecb9d1SAndroid Build Coastguard Worker 
488*bbecb9d1SAndroid Build Coastguard Worker       renderer.next_resource_id = 1;
489*bbecb9d1SAndroid Build Coastguard Worker    }
490*bbecb9d1SAndroid Build Coastguard Worker 
491*bbecb9d1SAndroid Build Coastguard Worker    if (renderer.next_sync_id > 1) {
492*bbecb9d1SAndroid Build Coastguard Worker       struct vtest_sync *sync, *tmp;
493*bbecb9d1SAndroid Build Coastguard Worker 
494*bbecb9d1SAndroid Build Coastguard Worker       LIST_FOR_EACH_ENTRY_SAFE(sync, tmp, &renderer.free_syncs, head) {
495*bbecb9d1SAndroid Build Coastguard Worker          assert(!sync->refcount);
496*bbecb9d1SAndroid Build Coastguard Worker          free(sync);
497*bbecb9d1SAndroid Build Coastguard Worker       }
498*bbecb9d1SAndroid Build Coastguard Worker       list_inithead(&renderer.free_syncs);
499*bbecb9d1SAndroid Build Coastguard Worker 
500*bbecb9d1SAndroid Build Coastguard Worker       renderer.next_sync_id = 1;
501*bbecb9d1SAndroid Build Coastguard Worker    }
502*bbecb9d1SAndroid Build Coastguard Worker 
503*bbecb9d1SAndroid Build Coastguard Worker    virgl_renderer_cleanup(&renderer);
504*bbecb9d1SAndroid Build Coastguard Worker }
505*bbecb9d1SAndroid Build Coastguard Worker 
vtest_new_context(struct vtest_input * input,int out_fd)506*bbecb9d1SAndroid Build Coastguard Worker static struct vtest_context *vtest_new_context(struct vtest_input *input,
507*bbecb9d1SAndroid Build Coastguard Worker                                                int out_fd)
508*bbecb9d1SAndroid Build Coastguard Worker {
509*bbecb9d1SAndroid Build Coastguard Worker    struct vtest_context *ctx;
510*bbecb9d1SAndroid Build Coastguard Worker 
511*bbecb9d1SAndroid Build Coastguard Worker    if (LIST_IS_EMPTY(&renderer.free_contexts)) {
512*bbecb9d1SAndroid Build Coastguard Worker       uint32_t i;
513*bbecb9d1SAndroid Build Coastguard Worker 
514*bbecb9d1SAndroid Build Coastguard Worker       ctx = malloc(sizeof(*ctx));
515*bbecb9d1SAndroid Build Coastguard Worker       if (!ctx) {
516*bbecb9d1SAndroid Build Coastguard Worker          return NULL;
517*bbecb9d1SAndroid Build Coastguard Worker       }
518*bbecb9d1SAndroid Build Coastguard Worker 
519*bbecb9d1SAndroid Build Coastguard Worker       ctx->resource_table = util_hash_table_create(u32_hash_func,
520*bbecb9d1SAndroid Build Coastguard Worker                                                    u32_equal_func,
521*bbecb9d1SAndroid Build Coastguard Worker                                                    resource_destroy_func);
522*bbecb9d1SAndroid Build Coastguard Worker       if (!ctx->resource_table) {
523*bbecb9d1SAndroid Build Coastguard Worker          free(ctx);
524*bbecb9d1SAndroid Build Coastguard Worker          return NULL;
525*bbecb9d1SAndroid Build Coastguard Worker       }
526*bbecb9d1SAndroid Build Coastguard Worker 
527*bbecb9d1SAndroid Build Coastguard Worker       ctx->sync_table = util_hash_table_create(u32_hash_func,
528*bbecb9d1SAndroid Build Coastguard Worker                                                u32_equal_func,
529*bbecb9d1SAndroid Build Coastguard Worker                                                sync_destroy_func);
530*bbecb9d1SAndroid Build Coastguard Worker       if (!ctx->sync_table) {
531*bbecb9d1SAndroid Build Coastguard Worker          util_hash_table_destroy(ctx->resource_table);
532*bbecb9d1SAndroid Build Coastguard Worker          free(ctx);
533*bbecb9d1SAndroid Build Coastguard Worker          return NULL;
534*bbecb9d1SAndroid Build Coastguard Worker       }
535*bbecb9d1SAndroid Build Coastguard Worker 
536*bbecb9d1SAndroid Build Coastguard Worker       for (i = 0; i < VTEST_MAX_TIMELINE_COUNT; i++) {
537*bbecb9d1SAndroid Build Coastguard Worker          struct vtest_timeline *timeline = &ctx->timelines[i];
538*bbecb9d1SAndroid Build Coastguard Worker          list_inithead(&timeline->submits);
539*bbecb9d1SAndroid Build Coastguard Worker       }
540*bbecb9d1SAndroid Build Coastguard Worker 
541*bbecb9d1SAndroid Build Coastguard Worker       list_inithead(&ctx->sync_waits);
542*bbecb9d1SAndroid Build Coastguard Worker 
543*bbecb9d1SAndroid Build Coastguard Worker       ctx->ctx_id = renderer.next_context_id++;
544*bbecb9d1SAndroid Build Coastguard Worker    } else {
545*bbecb9d1SAndroid Build Coastguard Worker       ctx = LIST_ENTRY(struct vtest_context, renderer.free_contexts.next, head);
546*bbecb9d1SAndroid Build Coastguard Worker       list_del(&ctx->head);
547*bbecb9d1SAndroid Build Coastguard Worker    }
548*bbecb9d1SAndroid Build Coastguard Worker 
549*bbecb9d1SAndroid Build Coastguard Worker    ctx->input = input;
550*bbecb9d1SAndroid Build Coastguard Worker    ctx->out_fd = out_fd;
551*bbecb9d1SAndroid Build Coastguard Worker 
552*bbecb9d1SAndroid Build Coastguard Worker    ctx->debug_name = NULL;
553*bbecb9d1SAndroid Build Coastguard Worker    /* By default we support version 0 unless VCMD_PROTOCOL_VERSION is sent */
554*bbecb9d1SAndroid Build Coastguard Worker    ctx->protocol_version = 0;
555*bbecb9d1SAndroid Build Coastguard Worker    ctx->capset_id = 0;
556*bbecb9d1SAndroid Build Coastguard Worker    ctx->context_initialized = false;
557*bbecb9d1SAndroid Build Coastguard Worker 
558*bbecb9d1SAndroid Build Coastguard Worker    return ctx;
559*bbecb9d1SAndroid Build Coastguard Worker }
560*bbecb9d1SAndroid Build Coastguard Worker 
vtest_free_context(struct vtest_context * ctx,bool cleanup)561*bbecb9d1SAndroid Build Coastguard Worker static void vtest_free_context(struct vtest_context *ctx, bool cleanup)
562*bbecb9d1SAndroid Build Coastguard Worker {
563*bbecb9d1SAndroid Build Coastguard Worker    if (cleanup) {
564*bbecb9d1SAndroid Build Coastguard Worker       util_hash_table_destroy(ctx->resource_table);
565*bbecb9d1SAndroid Build Coastguard Worker       util_hash_table_destroy(ctx->sync_table);
566*bbecb9d1SAndroid Build Coastguard Worker       free(ctx);
567*bbecb9d1SAndroid Build Coastguard Worker    } else {
568*bbecb9d1SAndroid Build Coastguard Worker       list_add(&ctx->head, &renderer.free_contexts);
569*bbecb9d1SAndroid Build Coastguard Worker    }
570*bbecb9d1SAndroid Build Coastguard Worker }
571*bbecb9d1SAndroid Build Coastguard Worker 
vtest_create_context(struct vtest_input * input,int out_fd,uint32_t length,struct vtest_context ** out_ctx)572*bbecb9d1SAndroid Build Coastguard Worker int vtest_create_context(struct vtest_input *input, int out_fd,
573*bbecb9d1SAndroid Build Coastguard Worker                          uint32_t length, struct vtest_context **out_ctx)
574*bbecb9d1SAndroid Build Coastguard Worker {
575*bbecb9d1SAndroid Build Coastguard Worker    struct vtest_context *ctx;
576*bbecb9d1SAndroid Build Coastguard Worker    char *vtestname;
577*bbecb9d1SAndroid Build Coastguard Worker    int ret;
578*bbecb9d1SAndroid Build Coastguard Worker 
579*bbecb9d1SAndroid Build Coastguard Worker    if (length > 1024 * 1024) {
580*bbecb9d1SAndroid Build Coastguard Worker       return -1;
581*bbecb9d1SAndroid Build Coastguard Worker    }
582*bbecb9d1SAndroid Build Coastguard Worker 
583*bbecb9d1SAndroid Build Coastguard Worker    ctx = vtest_new_context(input, out_fd);
584*bbecb9d1SAndroid Build Coastguard Worker    if (!ctx) {
585*bbecb9d1SAndroid Build Coastguard Worker       return -1;
586*bbecb9d1SAndroid Build Coastguard Worker    }
587*bbecb9d1SAndroid Build Coastguard Worker 
588*bbecb9d1SAndroid Build Coastguard Worker    vtestname = calloc(1, length + 1);
589*bbecb9d1SAndroid Build Coastguard Worker    if (!vtestname) {
590*bbecb9d1SAndroid Build Coastguard Worker       ret = -1;
591*bbecb9d1SAndroid Build Coastguard Worker       goto err;
592*bbecb9d1SAndroid Build Coastguard Worker    }
593*bbecb9d1SAndroid Build Coastguard Worker 
594*bbecb9d1SAndroid Build Coastguard Worker    ret = ctx->input->read(ctx->input, vtestname, length);
595*bbecb9d1SAndroid Build Coastguard Worker    if (ret != (int)length) {
596*bbecb9d1SAndroid Build Coastguard Worker       ret = -1;
597*bbecb9d1SAndroid Build Coastguard Worker       goto err;
598*bbecb9d1SAndroid Build Coastguard Worker    }
599*bbecb9d1SAndroid Build Coastguard Worker 
600*bbecb9d1SAndroid Build Coastguard Worker    ctx->debug_name = vtestname;
601*bbecb9d1SAndroid Build Coastguard Worker 
602*bbecb9d1SAndroid Build Coastguard Worker    list_addtail(&ctx->head, &renderer.active_contexts);
603*bbecb9d1SAndroid Build Coastguard Worker    *out_ctx = ctx;
604*bbecb9d1SAndroid Build Coastguard Worker 
605*bbecb9d1SAndroid Build Coastguard Worker    return 0;
606*bbecb9d1SAndroid Build Coastguard Worker 
607*bbecb9d1SAndroid Build Coastguard Worker err:
608*bbecb9d1SAndroid Build Coastguard Worker    free(vtestname);
609*bbecb9d1SAndroid Build Coastguard Worker    vtest_free_context(ctx, false);
610*bbecb9d1SAndroid Build Coastguard Worker    return ret;
611*bbecb9d1SAndroid Build Coastguard Worker }
612*bbecb9d1SAndroid Build Coastguard Worker 
vtest_lazy_init_context(struct vtest_context * ctx)613*bbecb9d1SAndroid Build Coastguard Worker int vtest_lazy_init_context(struct vtest_context *ctx)
614*bbecb9d1SAndroid Build Coastguard Worker {
615*bbecb9d1SAndroid Build Coastguard Worker    int ret;
616*bbecb9d1SAndroid Build Coastguard Worker 
617*bbecb9d1SAndroid Build Coastguard Worker    if (ctx->context_initialized)
618*bbecb9d1SAndroid Build Coastguard Worker       return 0;
619*bbecb9d1SAndroid Build Coastguard Worker 
620*bbecb9d1SAndroid Build Coastguard Worker    if (renderer.multi_clients && ctx->protocol_version < 3)
621*bbecb9d1SAndroid Build Coastguard Worker       return report_failed_call("protocol version too low", -EINVAL);
622*bbecb9d1SAndroid Build Coastguard Worker 
623*bbecb9d1SAndroid Build Coastguard Worker    if (ctx->capset_id) {
624*bbecb9d1SAndroid Build Coastguard Worker       ret = virgl_renderer_context_create_with_flags(ctx->ctx_id,
625*bbecb9d1SAndroid Build Coastguard Worker                                                      ctx->capset_id,
626*bbecb9d1SAndroid Build Coastguard Worker                                                      strlen(ctx->debug_name),
627*bbecb9d1SAndroid Build Coastguard Worker                                                      ctx->debug_name);
628*bbecb9d1SAndroid Build Coastguard Worker    } else {
629*bbecb9d1SAndroid Build Coastguard Worker       ret = virgl_renderer_context_create(ctx->ctx_id,
630*bbecb9d1SAndroid Build Coastguard Worker                                           strlen(ctx->debug_name),
631*bbecb9d1SAndroid Build Coastguard Worker                                           ctx->debug_name);
632*bbecb9d1SAndroid Build Coastguard Worker    }
633*bbecb9d1SAndroid Build Coastguard Worker    ctx->context_initialized = (ret == 0);
634*bbecb9d1SAndroid Build Coastguard Worker 
635*bbecb9d1SAndroid Build Coastguard Worker    return ret;
636*bbecb9d1SAndroid Build Coastguard Worker }
637*bbecb9d1SAndroid Build Coastguard Worker 
vtest_destroy_context(struct vtest_context * ctx)638*bbecb9d1SAndroid Build Coastguard Worker void vtest_destroy_context(struct vtest_context *ctx)
639*bbecb9d1SAndroid Build Coastguard Worker {
640*bbecb9d1SAndroid Build Coastguard Worker    struct vtest_sync_wait *wait, *wait_tmp;
641*bbecb9d1SAndroid Build Coastguard Worker    uint32_t i;
642*bbecb9d1SAndroid Build Coastguard Worker 
643*bbecb9d1SAndroid Build Coastguard Worker    if (renderer.current_context == ctx) {
644*bbecb9d1SAndroid Build Coastguard Worker       renderer.current_context = NULL;
645*bbecb9d1SAndroid Build Coastguard Worker    }
646*bbecb9d1SAndroid Build Coastguard Worker    list_del(&ctx->head);
647*bbecb9d1SAndroid Build Coastguard Worker 
648*bbecb9d1SAndroid Build Coastguard Worker    for (i = 0; i < VTEST_MAX_TIMELINE_COUNT; i++) {
649*bbecb9d1SAndroid Build Coastguard Worker       struct vtest_timeline *timeline = &ctx->timelines[i];
650*bbecb9d1SAndroid Build Coastguard Worker       struct vtest_timeline_submit *submit, *submit_tmp;
651*bbecb9d1SAndroid Build Coastguard Worker 
652*bbecb9d1SAndroid Build Coastguard Worker       LIST_FOR_EACH_ENTRY_SAFE(submit, submit_tmp, &timeline->submits, head)
653*bbecb9d1SAndroid Build Coastguard Worker          vtest_free_timeline_submit(submit);
654*bbecb9d1SAndroid Build Coastguard Worker       list_inithead(&timeline->submits);
655*bbecb9d1SAndroid Build Coastguard Worker    }
656*bbecb9d1SAndroid Build Coastguard Worker 
657*bbecb9d1SAndroid Build Coastguard Worker    LIST_FOR_EACH_ENTRY_SAFE(wait, wait_tmp, &ctx->sync_waits, head) {
658*bbecb9d1SAndroid Build Coastguard Worker       list_del(&wait->head);
659*bbecb9d1SAndroid Build Coastguard Worker       vtest_free_sync_wait(wait);
660*bbecb9d1SAndroid Build Coastguard Worker    }
661*bbecb9d1SAndroid Build Coastguard Worker    list_inithead(&ctx->sync_waits);
662*bbecb9d1SAndroid Build Coastguard Worker 
663*bbecb9d1SAndroid Build Coastguard Worker    free(ctx->debug_name);
664*bbecb9d1SAndroid Build Coastguard Worker    if (ctx->context_initialized)
665*bbecb9d1SAndroid Build Coastguard Worker       virgl_renderer_context_destroy(ctx->ctx_id);
666*bbecb9d1SAndroid Build Coastguard Worker    util_hash_table_clear(ctx->resource_table);
667*bbecb9d1SAndroid Build Coastguard Worker    util_hash_table_clear(ctx->sync_table);
668*bbecb9d1SAndroid Build Coastguard Worker    vtest_free_context(ctx, false);
669*bbecb9d1SAndroid Build Coastguard Worker }
670*bbecb9d1SAndroid Build Coastguard Worker 
vtest_poll_context(struct vtest_context * ctx)671*bbecb9d1SAndroid Build Coastguard Worker void vtest_poll_context(struct vtest_context *ctx)
672*bbecb9d1SAndroid Build Coastguard Worker {
673*bbecb9d1SAndroid Build Coastguard Worker    virgl_renderer_context_poll(ctx->ctx_id);
674*bbecb9d1SAndroid Build Coastguard Worker }
675*bbecb9d1SAndroid Build Coastguard Worker 
vtest_get_context_poll_fd(struct vtest_context * ctx)676*bbecb9d1SAndroid Build Coastguard Worker int vtest_get_context_poll_fd(struct vtest_context *ctx)
677*bbecb9d1SAndroid Build Coastguard Worker {
678*bbecb9d1SAndroid Build Coastguard Worker    return virgl_renderer_context_get_poll_fd(ctx->ctx_id);
679*bbecb9d1SAndroid Build Coastguard Worker }
680*bbecb9d1SAndroid Build Coastguard Worker 
vtest_set_current_context(struct vtest_context * ctx)681*bbecb9d1SAndroid Build Coastguard Worker void vtest_set_current_context(struct vtest_context *ctx)
682*bbecb9d1SAndroid Build Coastguard Worker {
683*bbecb9d1SAndroid Build Coastguard Worker    renderer.current_context = ctx;
684*bbecb9d1SAndroid Build Coastguard Worker }
685*bbecb9d1SAndroid Build Coastguard Worker 
vtest_get_current_context(void)686*bbecb9d1SAndroid Build Coastguard Worker static struct vtest_context *vtest_get_current_context(void)
687*bbecb9d1SAndroid Build Coastguard Worker {
688*bbecb9d1SAndroid Build Coastguard Worker    return renderer.current_context;
689*bbecb9d1SAndroid Build Coastguard Worker }
690*bbecb9d1SAndroid Build Coastguard Worker 
vtest_ping_protocol_version(UNUSED uint32_t length_dw)691*bbecb9d1SAndroid Build Coastguard Worker int vtest_ping_protocol_version(UNUSED uint32_t length_dw)
692*bbecb9d1SAndroid Build Coastguard Worker {
693*bbecb9d1SAndroid Build Coastguard Worker    struct vtest_context *ctx = vtest_get_current_context();
694*bbecb9d1SAndroid Build Coastguard Worker    uint32_t hdr_buf[VTEST_HDR_SIZE];
695*bbecb9d1SAndroid Build Coastguard Worker    int ret;
696*bbecb9d1SAndroid Build Coastguard Worker 
697*bbecb9d1SAndroid Build Coastguard Worker    hdr_buf[VTEST_CMD_LEN] = VCMD_PING_PROTOCOL_VERSION_SIZE;
698*bbecb9d1SAndroid Build Coastguard Worker    hdr_buf[VTEST_CMD_ID] = VCMD_PING_PROTOCOL_VERSION;
699*bbecb9d1SAndroid Build Coastguard Worker    ret = vtest_block_write(ctx->out_fd, hdr_buf, sizeof(hdr_buf));
700*bbecb9d1SAndroid Build Coastguard Worker    if (ret < 0) {
701*bbecb9d1SAndroid Build Coastguard Worker       return ret;
702*bbecb9d1SAndroid Build Coastguard Worker    }
703*bbecb9d1SAndroid Build Coastguard Worker 
704*bbecb9d1SAndroid Build Coastguard Worker    return 0;
705*bbecb9d1SAndroid Build Coastguard Worker }
706*bbecb9d1SAndroid Build Coastguard Worker 
vtest_protocol_version(UNUSED uint32_t length_dw)707*bbecb9d1SAndroid Build Coastguard Worker int vtest_protocol_version(UNUSED uint32_t length_dw)
708*bbecb9d1SAndroid Build Coastguard Worker {
709*bbecb9d1SAndroid Build Coastguard Worker    struct vtest_context *ctx = vtest_get_current_context();
710*bbecb9d1SAndroid Build Coastguard Worker    uint32_t hdr_buf[VTEST_HDR_SIZE];
711*bbecb9d1SAndroid Build Coastguard Worker    uint32_t version_buf[VCMD_PROTOCOL_VERSION_SIZE];
712*bbecb9d1SAndroid Build Coastguard Worker    unsigned version;
713*bbecb9d1SAndroid Build Coastguard Worker    int ret;
714*bbecb9d1SAndroid Build Coastguard Worker 
715*bbecb9d1SAndroid Build Coastguard Worker    ret = ctx->input->read(ctx->input, &version_buf, sizeof(version_buf));
716*bbecb9d1SAndroid Build Coastguard Worker    if (ret != sizeof(version_buf))
717*bbecb9d1SAndroid Build Coastguard Worker       return -1;
718*bbecb9d1SAndroid Build Coastguard Worker 
719*bbecb9d1SAndroid Build Coastguard Worker    version = MIN2(version_buf[VCMD_PROTOCOL_VERSION_VERSION],
720*bbecb9d1SAndroid Build Coastguard Worker                   VTEST_PROTOCOL_VERSION);
721*bbecb9d1SAndroid Build Coastguard Worker 
722*bbecb9d1SAndroid Build Coastguard Worker    /*
723*bbecb9d1SAndroid Build Coastguard Worker     * We've deprecated protocol version 1. All of it's called sites are being
724*bbecb9d1SAndroid Build Coastguard Worker     * moved protocol version 2. If the server supports version 2 and the guest
725*bbecb9d1SAndroid Build Coastguard Worker     * supports verison 1, fall back to version 0.
726*bbecb9d1SAndroid Build Coastguard Worker     */
727*bbecb9d1SAndroid Build Coastguard Worker    if (version == 1) {
728*bbecb9d1SAndroid Build Coastguard Worker       printf("Older guest Mesa detected, fallbacking to protocol version 0\n");
729*bbecb9d1SAndroid Build Coastguard Worker       version = 0;
730*bbecb9d1SAndroid Build Coastguard Worker    }
731*bbecb9d1SAndroid Build Coastguard Worker 
732*bbecb9d1SAndroid Build Coastguard Worker    /* Protocol version 2 requires shm support. */
733*bbecb9d1SAndroid Build Coastguard Worker    if (!vtest_shm_check()) {
734*bbecb9d1SAndroid Build Coastguard Worker       printf("Shared memory not supported, fallbacking to protocol version 0\n");
735*bbecb9d1SAndroid Build Coastguard Worker       version = 0;
736*bbecb9d1SAndroid Build Coastguard Worker    }
737*bbecb9d1SAndroid Build Coastguard Worker 
738*bbecb9d1SAndroid Build Coastguard Worker    if (renderer.multi_clients && version < 3)
739*bbecb9d1SAndroid Build Coastguard Worker       return report_failed_call("protocol version too low", -EINVAL);
740*bbecb9d1SAndroid Build Coastguard Worker 
741*bbecb9d1SAndroid Build Coastguard Worker    ctx->protocol_version = version;
742*bbecb9d1SAndroid Build Coastguard Worker 
743*bbecb9d1SAndroid Build Coastguard Worker    hdr_buf[VTEST_CMD_LEN] = VCMD_PROTOCOL_VERSION_SIZE;
744*bbecb9d1SAndroid Build Coastguard Worker    hdr_buf[VTEST_CMD_ID] = VCMD_PROTOCOL_VERSION;
745*bbecb9d1SAndroid Build Coastguard Worker 
746*bbecb9d1SAndroid Build Coastguard Worker    version_buf[VCMD_PROTOCOL_VERSION_VERSION] = ctx->protocol_version;
747*bbecb9d1SAndroid Build Coastguard Worker 
748*bbecb9d1SAndroid Build Coastguard Worker    ret = vtest_block_write(ctx->out_fd, hdr_buf, sizeof(hdr_buf));
749*bbecb9d1SAndroid Build Coastguard Worker    if (ret < 0) {
750*bbecb9d1SAndroid Build Coastguard Worker       return ret;
751*bbecb9d1SAndroid Build Coastguard Worker    }
752*bbecb9d1SAndroid Build Coastguard Worker 
753*bbecb9d1SAndroid Build Coastguard Worker    ret = vtest_block_write(ctx->out_fd, version_buf, sizeof(version_buf));
754*bbecb9d1SAndroid Build Coastguard Worker    if (ret < 0) {
755*bbecb9d1SAndroid Build Coastguard Worker       return ret;
756*bbecb9d1SAndroid Build Coastguard Worker    }
757*bbecb9d1SAndroid Build Coastguard Worker 
758*bbecb9d1SAndroid Build Coastguard Worker    return 0;
759*bbecb9d1SAndroid Build Coastguard Worker }
760*bbecb9d1SAndroid Build Coastguard Worker 
vtest_get_param(UNUSED uint32_t length_dw)761*bbecb9d1SAndroid Build Coastguard Worker int vtest_get_param(UNUSED uint32_t length_dw)
762*bbecb9d1SAndroid Build Coastguard Worker {
763*bbecb9d1SAndroid Build Coastguard Worker    struct vtest_context *ctx = vtest_get_current_context();
764*bbecb9d1SAndroid Build Coastguard Worker    uint32_t get_param_buf[VCMD_GET_PARAM_SIZE];
765*bbecb9d1SAndroid Build Coastguard Worker    uint32_t resp_buf[VTEST_HDR_SIZE + 2];
766*bbecb9d1SAndroid Build Coastguard Worker    uint32_t param;
767*bbecb9d1SAndroid Build Coastguard Worker    uint32_t *resp;
768*bbecb9d1SAndroid Build Coastguard Worker    int ret;
769*bbecb9d1SAndroid Build Coastguard Worker 
770*bbecb9d1SAndroid Build Coastguard Worker    ret = ctx->input->read(ctx->input, get_param_buf, sizeof(get_param_buf));
771*bbecb9d1SAndroid Build Coastguard Worker    if (ret != sizeof(get_param_buf))
772*bbecb9d1SAndroid Build Coastguard Worker       return -1;
773*bbecb9d1SAndroid Build Coastguard Worker 
774*bbecb9d1SAndroid Build Coastguard Worker    param = get_param_buf[VCMD_GET_PARAM_PARAM];
775*bbecb9d1SAndroid Build Coastguard Worker 
776*bbecb9d1SAndroid Build Coastguard Worker    resp_buf[VTEST_CMD_LEN] = 2;
777*bbecb9d1SAndroid Build Coastguard Worker    resp_buf[VTEST_CMD_ID] = VCMD_GET_PARAM;
778*bbecb9d1SAndroid Build Coastguard Worker    resp = &resp_buf[VTEST_CMD_DATA_START];
779*bbecb9d1SAndroid Build Coastguard Worker    switch (param) {
780*bbecb9d1SAndroid Build Coastguard Worker    case VCMD_PARAM_MAX_TIMELINE_COUNT:
781*bbecb9d1SAndroid Build Coastguard Worker       resp[0] = true;
782*bbecb9d1SAndroid Build Coastguard Worker       /* TODO until we have a timerfd */
783*bbecb9d1SAndroid Build Coastguard Worker #ifdef HAVE_EVENTFD_H
784*bbecb9d1SAndroid Build Coastguard Worker       if (!getenv("VIRGL_DISABLE_MT"))
785*bbecb9d1SAndroid Build Coastguard Worker          resp[1] = VTEST_MAX_TIMELINE_COUNT;
786*bbecb9d1SAndroid Build Coastguard Worker       else
787*bbecb9d1SAndroid Build Coastguard Worker          resp[1] = 0;
788*bbecb9d1SAndroid Build Coastguard Worker #else
789*bbecb9d1SAndroid Build Coastguard Worker       resp[1] = 0;
790*bbecb9d1SAndroid Build Coastguard Worker #endif
791*bbecb9d1SAndroid Build Coastguard Worker       break;
792*bbecb9d1SAndroid Build Coastguard Worker    default:
793*bbecb9d1SAndroid Build Coastguard Worker       resp[0] = false;
794*bbecb9d1SAndroid Build Coastguard Worker       resp[1] = 0;
795*bbecb9d1SAndroid Build Coastguard Worker       break;
796*bbecb9d1SAndroid Build Coastguard Worker    }
797*bbecb9d1SAndroid Build Coastguard Worker 
798*bbecb9d1SAndroid Build Coastguard Worker    ret = vtest_block_write(ctx->out_fd, resp_buf, sizeof(resp_buf));
799*bbecb9d1SAndroid Build Coastguard Worker    if (ret < 0)
800*bbecb9d1SAndroid Build Coastguard Worker       return -1;
801*bbecb9d1SAndroid Build Coastguard Worker 
802*bbecb9d1SAndroid Build Coastguard Worker    return 0;
803*bbecb9d1SAndroid Build Coastguard Worker }
804*bbecb9d1SAndroid Build Coastguard Worker 
vtest_get_capset(UNUSED uint32_t length_dw)805*bbecb9d1SAndroid Build Coastguard Worker int vtest_get_capset(UNUSED uint32_t length_dw)
806*bbecb9d1SAndroid Build Coastguard Worker {
807*bbecb9d1SAndroid Build Coastguard Worker    struct vtest_context *ctx = vtest_get_current_context();
808*bbecb9d1SAndroid Build Coastguard Worker    uint32_t get_capset_buf[VCMD_GET_CAPSET_SIZE];
809*bbecb9d1SAndroid Build Coastguard Worker    uint32_t resp_buf[VTEST_HDR_SIZE + 1];
810*bbecb9d1SAndroid Build Coastguard Worker    uint32_t id;
811*bbecb9d1SAndroid Build Coastguard Worker    uint32_t version;
812*bbecb9d1SAndroid Build Coastguard Worker    uint32_t max_version;
813*bbecb9d1SAndroid Build Coastguard Worker    uint32_t max_size;
814*bbecb9d1SAndroid Build Coastguard Worker    void *caps;
815*bbecb9d1SAndroid Build Coastguard Worker    int ret;
816*bbecb9d1SAndroid Build Coastguard Worker 
817*bbecb9d1SAndroid Build Coastguard Worker    ret = ctx->input->read(ctx->input, get_capset_buf, sizeof(get_capset_buf));
818*bbecb9d1SAndroid Build Coastguard Worker    if (ret != sizeof(get_capset_buf))
819*bbecb9d1SAndroid Build Coastguard Worker       return -1;
820*bbecb9d1SAndroid Build Coastguard Worker 
821*bbecb9d1SAndroid Build Coastguard Worker    id = get_capset_buf[VCMD_GET_CAPSET_ID];
822*bbecb9d1SAndroid Build Coastguard Worker    version = get_capset_buf[VCMD_GET_CAPSET_VERSION];
823*bbecb9d1SAndroid Build Coastguard Worker 
824*bbecb9d1SAndroid Build Coastguard Worker    virgl_renderer_get_cap_set(id, &max_version, &max_size);
825*bbecb9d1SAndroid Build Coastguard Worker 
826*bbecb9d1SAndroid Build Coastguard Worker    /* unsupported id or version */
827*bbecb9d1SAndroid Build Coastguard Worker    if ((!max_version && !max_size) || version > max_version) {
828*bbecb9d1SAndroid Build Coastguard Worker       resp_buf[VTEST_CMD_LEN] = 1;
829*bbecb9d1SAndroid Build Coastguard Worker       resp_buf[VTEST_CMD_ID] = VCMD_GET_CAPSET;
830*bbecb9d1SAndroid Build Coastguard Worker       resp_buf[VTEST_CMD_DATA_START] = false;
831*bbecb9d1SAndroid Build Coastguard Worker       return vtest_block_write(ctx->out_fd, resp_buf, sizeof(resp_buf));
832*bbecb9d1SAndroid Build Coastguard Worker    }
833*bbecb9d1SAndroid Build Coastguard Worker 
834*bbecb9d1SAndroid Build Coastguard Worker    if (max_size % 4)
835*bbecb9d1SAndroid Build Coastguard Worker       return -EINVAL;
836*bbecb9d1SAndroid Build Coastguard Worker 
837*bbecb9d1SAndroid Build Coastguard Worker    caps = malloc(max_size);
838*bbecb9d1SAndroid Build Coastguard Worker    if (!caps)
839*bbecb9d1SAndroid Build Coastguard Worker       return -ENOMEM;
840*bbecb9d1SAndroid Build Coastguard Worker 
841*bbecb9d1SAndroid Build Coastguard Worker    virgl_renderer_fill_caps(id, version, caps);
842*bbecb9d1SAndroid Build Coastguard Worker 
843*bbecb9d1SAndroid Build Coastguard Worker    resp_buf[VTEST_CMD_LEN] = 1 + max_size / 4;
844*bbecb9d1SAndroid Build Coastguard Worker    resp_buf[VTEST_CMD_ID] = VCMD_GET_CAPSET;
845*bbecb9d1SAndroid Build Coastguard Worker    resp_buf[VTEST_CMD_DATA_START] = true;
846*bbecb9d1SAndroid Build Coastguard Worker    ret = vtest_block_write(ctx->out_fd, resp_buf, sizeof(resp_buf));
847*bbecb9d1SAndroid Build Coastguard Worker    if (ret >= 0)
848*bbecb9d1SAndroid Build Coastguard Worker       ret = vtest_block_write(ctx->out_fd, caps, max_size);
849*bbecb9d1SAndroid Build Coastguard Worker 
850*bbecb9d1SAndroid Build Coastguard Worker    free(caps);
851*bbecb9d1SAndroid Build Coastguard Worker    return ret >= 0 ? 0 : ret;
852*bbecb9d1SAndroid Build Coastguard Worker }
853*bbecb9d1SAndroid Build Coastguard Worker 
vtest_context_init(UNUSED uint32_t length_dw)854*bbecb9d1SAndroid Build Coastguard Worker int vtest_context_init(UNUSED uint32_t length_dw)
855*bbecb9d1SAndroid Build Coastguard Worker {
856*bbecb9d1SAndroid Build Coastguard Worker    struct vtest_context *ctx = vtest_get_current_context();
857*bbecb9d1SAndroid Build Coastguard Worker    uint32_t context_init_buf[VCMD_CONTEXT_INIT_SIZE];
858*bbecb9d1SAndroid Build Coastguard Worker    uint32_t capset_id;
859*bbecb9d1SAndroid Build Coastguard Worker    int ret;
860*bbecb9d1SAndroid Build Coastguard Worker 
861*bbecb9d1SAndroid Build Coastguard Worker    ret = ctx->input->read(ctx->input, context_init_buf, sizeof(context_init_buf));
862*bbecb9d1SAndroid Build Coastguard Worker    if (ret != sizeof(context_init_buf))
863*bbecb9d1SAndroid Build Coastguard Worker       return -1;
864*bbecb9d1SAndroid Build Coastguard Worker 
865*bbecb9d1SAndroid Build Coastguard Worker    capset_id = context_init_buf[VCMD_CONTEXT_INIT_CAPSET_ID];
866*bbecb9d1SAndroid Build Coastguard Worker    if (!capset_id)
867*bbecb9d1SAndroid Build Coastguard Worker       return -EINVAL;
868*bbecb9d1SAndroid Build Coastguard Worker 
869*bbecb9d1SAndroid Build Coastguard Worker    if (ctx->context_initialized) {
870*bbecb9d1SAndroid Build Coastguard Worker       return ctx->capset_id == capset_id ? 0 : -EINVAL;
871*bbecb9d1SAndroid Build Coastguard Worker    }
872*bbecb9d1SAndroid Build Coastguard Worker 
873*bbecb9d1SAndroid Build Coastguard Worker    ctx->capset_id = capset_id;
874*bbecb9d1SAndroid Build Coastguard Worker 
875*bbecb9d1SAndroid Build Coastguard Worker    return vtest_lazy_init_context(ctx);
876*bbecb9d1SAndroid Build Coastguard Worker }
877*bbecb9d1SAndroid Build Coastguard Worker 
vtest_send_caps2(UNUSED uint32_t length_dw)878*bbecb9d1SAndroid Build Coastguard Worker int vtest_send_caps2(UNUSED uint32_t length_dw)
879*bbecb9d1SAndroid Build Coastguard Worker {
880*bbecb9d1SAndroid Build Coastguard Worker    struct vtest_context *ctx = vtest_get_current_context();
881*bbecb9d1SAndroid Build Coastguard Worker    uint32_t hdr_buf[2];
882*bbecb9d1SAndroid Build Coastguard Worker    void *caps_buf;
883*bbecb9d1SAndroid Build Coastguard Worker    int ret;
884*bbecb9d1SAndroid Build Coastguard Worker    uint32_t max_ver, max_size;
885*bbecb9d1SAndroid Build Coastguard Worker 
886*bbecb9d1SAndroid Build Coastguard Worker    virgl_renderer_get_cap_set(2, &max_ver, &max_size);
887*bbecb9d1SAndroid Build Coastguard Worker 
888*bbecb9d1SAndroid Build Coastguard Worker    if (max_size == 0) {
889*bbecb9d1SAndroid Build Coastguard Worker       return -1;
890*bbecb9d1SAndroid Build Coastguard Worker    }
891*bbecb9d1SAndroid Build Coastguard Worker 
892*bbecb9d1SAndroid Build Coastguard Worker    caps_buf = malloc(max_size);
893*bbecb9d1SAndroid Build Coastguard Worker    if (!caps_buf) {
894*bbecb9d1SAndroid Build Coastguard Worker       return -1;
895*bbecb9d1SAndroid Build Coastguard Worker    }
896*bbecb9d1SAndroid Build Coastguard Worker 
897*bbecb9d1SAndroid Build Coastguard Worker    virgl_renderer_fill_caps(2, 1, caps_buf);
898*bbecb9d1SAndroid Build Coastguard Worker 
899*bbecb9d1SAndroid Build Coastguard Worker    hdr_buf[0] = max_size + 1;
900*bbecb9d1SAndroid Build Coastguard Worker    hdr_buf[1] = 2;
901*bbecb9d1SAndroid Build Coastguard Worker    ret = vtest_block_write(ctx->out_fd, hdr_buf, 8);
902*bbecb9d1SAndroid Build Coastguard Worker    if (ret < 0) {
903*bbecb9d1SAndroid Build Coastguard Worker       goto end;
904*bbecb9d1SAndroid Build Coastguard Worker    }
905*bbecb9d1SAndroid Build Coastguard Worker 
906*bbecb9d1SAndroid Build Coastguard Worker    ret = vtest_block_write(ctx->out_fd, caps_buf, max_size);
907*bbecb9d1SAndroid Build Coastguard Worker    if (ret < 0) {
908*bbecb9d1SAndroid Build Coastguard Worker       goto end;
909*bbecb9d1SAndroid Build Coastguard Worker    }
910*bbecb9d1SAndroid Build Coastguard Worker 
911*bbecb9d1SAndroid Build Coastguard Worker end:
912*bbecb9d1SAndroid Build Coastguard Worker    free(caps_buf);
913*bbecb9d1SAndroid Build Coastguard Worker    return 0;
914*bbecb9d1SAndroid Build Coastguard Worker }
915*bbecb9d1SAndroid Build Coastguard Worker 
vtest_send_caps(UNUSED uint32_t length_dw)916*bbecb9d1SAndroid Build Coastguard Worker int vtest_send_caps(UNUSED uint32_t length_dw)
917*bbecb9d1SAndroid Build Coastguard Worker {
918*bbecb9d1SAndroid Build Coastguard Worker    struct vtest_context *ctx = vtest_get_current_context();
919*bbecb9d1SAndroid Build Coastguard Worker    uint32_t  max_ver, max_size;
920*bbecb9d1SAndroid Build Coastguard Worker    void *caps_buf;
921*bbecb9d1SAndroid Build Coastguard Worker    uint32_t hdr_buf[2];
922*bbecb9d1SAndroid Build Coastguard Worker    int ret;
923*bbecb9d1SAndroid Build Coastguard Worker 
924*bbecb9d1SAndroid Build Coastguard Worker    virgl_renderer_get_cap_set(1, &max_ver, &max_size);
925*bbecb9d1SAndroid Build Coastguard Worker 
926*bbecb9d1SAndroid Build Coastguard Worker    caps_buf = malloc(max_size);
927*bbecb9d1SAndroid Build Coastguard Worker    if (!caps_buf) {
928*bbecb9d1SAndroid Build Coastguard Worker       return -1;
929*bbecb9d1SAndroid Build Coastguard Worker    }
930*bbecb9d1SAndroid Build Coastguard Worker 
931*bbecb9d1SAndroid Build Coastguard Worker    virgl_renderer_fill_caps(1, 1, caps_buf);
932*bbecb9d1SAndroid Build Coastguard Worker 
933*bbecb9d1SAndroid Build Coastguard Worker    hdr_buf[0] = max_size + 1;
934*bbecb9d1SAndroid Build Coastguard Worker    hdr_buf[1] = 1;
935*bbecb9d1SAndroid Build Coastguard Worker    ret = vtest_block_write(ctx->out_fd, hdr_buf, 8);
936*bbecb9d1SAndroid Build Coastguard Worker    if (ret < 0) {
937*bbecb9d1SAndroid Build Coastguard Worker       goto end;
938*bbecb9d1SAndroid Build Coastguard Worker    }
939*bbecb9d1SAndroid Build Coastguard Worker 
940*bbecb9d1SAndroid Build Coastguard Worker    ret = vtest_block_write(ctx->out_fd, caps_buf, max_size);
941*bbecb9d1SAndroid Build Coastguard Worker    if (ret < 0) {
942*bbecb9d1SAndroid Build Coastguard Worker       goto end;
943*bbecb9d1SAndroid Build Coastguard Worker    }
944*bbecb9d1SAndroid Build Coastguard Worker 
945*bbecb9d1SAndroid Build Coastguard Worker end:
946*bbecb9d1SAndroid Build Coastguard Worker    free(caps_buf);
947*bbecb9d1SAndroid Build Coastguard Worker    return 0;
948*bbecb9d1SAndroid Build Coastguard Worker }
949*bbecb9d1SAndroid Build Coastguard Worker 
vtest_create_resource_decode_args(struct vtest_context * ctx,struct virgl_renderer_resource_create_args * args)950*bbecb9d1SAndroid Build Coastguard Worker static int vtest_create_resource_decode_args(struct vtest_context *ctx,
951*bbecb9d1SAndroid Build Coastguard Worker                                              struct virgl_renderer_resource_create_args *args)
952*bbecb9d1SAndroid Build Coastguard Worker {
953*bbecb9d1SAndroid Build Coastguard Worker    uint32_t res_create_buf[VCMD_RES_CREATE_SIZE];
954*bbecb9d1SAndroid Build Coastguard Worker    int ret;
955*bbecb9d1SAndroid Build Coastguard Worker 
956*bbecb9d1SAndroid Build Coastguard Worker    ret = ctx->input->read(ctx->input, &res_create_buf,
957*bbecb9d1SAndroid Build Coastguard Worker                           sizeof(res_create_buf));
958*bbecb9d1SAndroid Build Coastguard Worker    if (ret != sizeof(res_create_buf)) {
959*bbecb9d1SAndroid Build Coastguard Worker       return -1;
960*bbecb9d1SAndroid Build Coastguard Worker    }
961*bbecb9d1SAndroid Build Coastguard Worker 
962*bbecb9d1SAndroid Build Coastguard Worker    args->handle = res_create_buf[VCMD_RES_CREATE_RES_HANDLE];
963*bbecb9d1SAndroid Build Coastguard Worker    args->target = res_create_buf[VCMD_RES_CREATE_TARGET];
964*bbecb9d1SAndroid Build Coastguard Worker    args->format = res_create_buf[VCMD_RES_CREATE_FORMAT];
965*bbecb9d1SAndroid Build Coastguard Worker    args->bind = res_create_buf[VCMD_RES_CREATE_BIND];
966*bbecb9d1SAndroid Build Coastguard Worker 
967*bbecb9d1SAndroid Build Coastguard Worker    args->width = res_create_buf[VCMD_RES_CREATE_WIDTH];
968*bbecb9d1SAndroid Build Coastguard Worker    args->height = res_create_buf[VCMD_RES_CREATE_HEIGHT];
969*bbecb9d1SAndroid Build Coastguard Worker    args->depth = res_create_buf[VCMD_RES_CREATE_DEPTH];
970*bbecb9d1SAndroid Build Coastguard Worker    args->array_size = res_create_buf[VCMD_RES_CREATE_ARRAY_SIZE];
971*bbecb9d1SAndroid Build Coastguard Worker    args->last_level = res_create_buf[VCMD_RES_CREATE_LAST_LEVEL];
972*bbecb9d1SAndroid Build Coastguard Worker    args->nr_samples = res_create_buf[VCMD_RES_CREATE_NR_SAMPLES];
973*bbecb9d1SAndroid Build Coastguard Worker    args->flags = 0;
974*bbecb9d1SAndroid Build Coastguard Worker 
975*bbecb9d1SAndroid Build Coastguard Worker    return 0;
976*bbecb9d1SAndroid Build Coastguard Worker }
977*bbecb9d1SAndroid Build Coastguard Worker 
vtest_create_resource_decode_args2(struct vtest_context * ctx,struct virgl_renderer_resource_create_args * args,size_t * shm_size)978*bbecb9d1SAndroid Build Coastguard Worker static int vtest_create_resource_decode_args2(struct vtest_context *ctx,
979*bbecb9d1SAndroid Build Coastguard Worker                                               struct virgl_renderer_resource_create_args *args,
980*bbecb9d1SAndroid Build Coastguard Worker                                               size_t *shm_size)
981*bbecb9d1SAndroid Build Coastguard Worker {
982*bbecb9d1SAndroid Build Coastguard Worker    uint32_t res_create_buf[VCMD_RES_CREATE2_SIZE];
983*bbecb9d1SAndroid Build Coastguard Worker    int ret;
984*bbecb9d1SAndroid Build Coastguard Worker 
985*bbecb9d1SAndroid Build Coastguard Worker    ret = ctx->input->read(ctx->input, &res_create_buf,
986*bbecb9d1SAndroid Build Coastguard Worker                           sizeof(res_create_buf));
987*bbecb9d1SAndroid Build Coastguard Worker    if (ret != sizeof(res_create_buf)) {
988*bbecb9d1SAndroid Build Coastguard Worker       return -1;
989*bbecb9d1SAndroid Build Coastguard Worker    }
990*bbecb9d1SAndroid Build Coastguard Worker 
991*bbecb9d1SAndroid Build Coastguard Worker    args->handle = res_create_buf[VCMD_RES_CREATE2_RES_HANDLE];
992*bbecb9d1SAndroid Build Coastguard Worker    args->target = res_create_buf[VCMD_RES_CREATE2_TARGET];
993*bbecb9d1SAndroid Build Coastguard Worker    args->format = res_create_buf[VCMD_RES_CREATE2_FORMAT];
994*bbecb9d1SAndroid Build Coastguard Worker    args->bind = res_create_buf[VCMD_RES_CREATE2_BIND];
995*bbecb9d1SAndroid Build Coastguard Worker 
996*bbecb9d1SAndroid Build Coastguard Worker    args->width = res_create_buf[VCMD_RES_CREATE2_WIDTH];
997*bbecb9d1SAndroid Build Coastguard Worker    args->height = res_create_buf[VCMD_RES_CREATE2_HEIGHT];
998*bbecb9d1SAndroid Build Coastguard Worker    args->depth = res_create_buf[VCMD_RES_CREATE2_DEPTH];
999*bbecb9d1SAndroid Build Coastguard Worker    args->array_size = res_create_buf[VCMD_RES_CREATE2_ARRAY_SIZE];
1000*bbecb9d1SAndroid Build Coastguard Worker    args->last_level = res_create_buf[VCMD_RES_CREATE2_LAST_LEVEL];
1001*bbecb9d1SAndroid Build Coastguard Worker    args->nr_samples = res_create_buf[VCMD_RES_CREATE2_NR_SAMPLES];
1002*bbecb9d1SAndroid Build Coastguard Worker    args->flags = 0;
1003*bbecb9d1SAndroid Build Coastguard Worker 
1004*bbecb9d1SAndroid Build Coastguard Worker    *shm_size = res_create_buf[VCMD_RES_CREATE2_DATA_SIZE];
1005*bbecb9d1SAndroid Build Coastguard Worker 
1006*bbecb9d1SAndroid Build Coastguard Worker    return 0;
1007*bbecb9d1SAndroid Build Coastguard Worker }
1008*bbecb9d1SAndroid Build Coastguard Worker 
vtest_create_resource_setup_shm(struct vtest_resource * res,size_t size)1009*bbecb9d1SAndroid Build Coastguard Worker static int vtest_create_resource_setup_shm(struct vtest_resource *res,
1010*bbecb9d1SAndroid Build Coastguard Worker                                            size_t size)
1011*bbecb9d1SAndroid Build Coastguard Worker {
1012*bbecb9d1SAndroid Build Coastguard Worker    int fd;
1013*bbecb9d1SAndroid Build Coastguard Worker    void *ptr;
1014*bbecb9d1SAndroid Build Coastguard Worker 
1015*bbecb9d1SAndroid Build Coastguard Worker    fd = vtest_new_shm(res->res_id, size);
1016*bbecb9d1SAndroid Build Coastguard Worker    if (fd < 0)
1017*bbecb9d1SAndroid Build Coastguard Worker       return report_failed_call("vtest_new_shm", fd);
1018*bbecb9d1SAndroid Build Coastguard Worker 
1019*bbecb9d1SAndroid Build Coastguard Worker    ptr = mmap(NULL, size, PROT_WRITE | PROT_READ, MAP_SHARED, fd, 0);
1020*bbecb9d1SAndroid Build Coastguard Worker    if (ptr == MAP_FAILED) {
1021*bbecb9d1SAndroid Build Coastguard Worker       close(fd);
1022*bbecb9d1SAndroid Build Coastguard Worker       return -1;
1023*bbecb9d1SAndroid Build Coastguard Worker    }
1024*bbecb9d1SAndroid Build Coastguard Worker 
1025*bbecb9d1SAndroid Build Coastguard Worker    res->iov.iov_base = ptr;
1026*bbecb9d1SAndroid Build Coastguard Worker    res->iov.iov_len = size;
1027*bbecb9d1SAndroid Build Coastguard Worker 
1028*bbecb9d1SAndroid Build Coastguard Worker    return fd;
1029*bbecb9d1SAndroid Build Coastguard Worker }
1030*bbecb9d1SAndroid Build Coastguard Worker 
vtest_create_resource_internal(struct vtest_context * ctx,uint32_t cmd_id,struct virgl_renderer_resource_create_args * args,size_t shm_size)1031*bbecb9d1SAndroid Build Coastguard Worker static int vtest_create_resource_internal(struct vtest_context *ctx,
1032*bbecb9d1SAndroid Build Coastguard Worker                                           uint32_t cmd_id,
1033*bbecb9d1SAndroid Build Coastguard Worker                                           struct virgl_renderer_resource_create_args *args,
1034*bbecb9d1SAndroid Build Coastguard Worker                                           size_t shm_size)
1035*bbecb9d1SAndroid Build Coastguard Worker {
1036*bbecb9d1SAndroid Build Coastguard Worker    struct vtest_resource *res;
1037*bbecb9d1SAndroid Build Coastguard Worker    int ret;
1038*bbecb9d1SAndroid Build Coastguard Worker 
1039*bbecb9d1SAndroid Build Coastguard Worker    if (ctx->protocol_version >= 3) {
1040*bbecb9d1SAndroid Build Coastguard Worker       if (args->handle)
1041*bbecb9d1SAndroid Build Coastguard Worker          return -EINVAL;
1042*bbecb9d1SAndroid Build Coastguard Worker    } else {
1043*bbecb9d1SAndroid Build Coastguard Worker       // Check that the handle doesn't already exist.
1044*bbecb9d1SAndroid Build Coastguard Worker       if (util_hash_table_get(ctx->resource_table, intptr_to_pointer(args->handle))) {
1045*bbecb9d1SAndroid Build Coastguard Worker          return -EEXIST;
1046*bbecb9d1SAndroid Build Coastguard Worker       }
1047*bbecb9d1SAndroid Build Coastguard Worker    }
1048*bbecb9d1SAndroid Build Coastguard Worker 
1049*bbecb9d1SAndroid Build Coastguard Worker    res = vtest_new_resource(args->handle);
1050*bbecb9d1SAndroid Build Coastguard Worker    if (!res)
1051*bbecb9d1SAndroid Build Coastguard Worker       return -ENOMEM;
1052*bbecb9d1SAndroid Build Coastguard Worker    args->handle = res->res_id;
1053*bbecb9d1SAndroid Build Coastguard Worker 
1054*bbecb9d1SAndroid Build Coastguard Worker    ret = virgl_renderer_resource_create(args, NULL, 0);
1055*bbecb9d1SAndroid Build Coastguard Worker    if (ret) {
1056*bbecb9d1SAndroid Build Coastguard Worker       vtest_unref_resource(res);
1057*bbecb9d1SAndroid Build Coastguard Worker       return report_failed_call("virgl_renderer_resource_create", ret);
1058*bbecb9d1SAndroid Build Coastguard Worker    }
1059*bbecb9d1SAndroid Build Coastguard Worker 
1060*bbecb9d1SAndroid Build Coastguard Worker    virgl_renderer_ctx_attach_resource(ctx->ctx_id, res->res_id);
1061*bbecb9d1SAndroid Build Coastguard Worker 
1062*bbecb9d1SAndroid Build Coastguard Worker    if (ctx->protocol_version >= 3) {
1063*bbecb9d1SAndroid Build Coastguard Worker       uint32_t resp_buf[VTEST_HDR_SIZE + 1] = {
1064*bbecb9d1SAndroid Build Coastguard Worker          [VTEST_CMD_LEN] = 1,
1065*bbecb9d1SAndroid Build Coastguard Worker          [VTEST_CMD_ID] = cmd_id,
1066*bbecb9d1SAndroid Build Coastguard Worker          [VTEST_CMD_DATA_START] = res->res_id,
1067*bbecb9d1SAndroid Build Coastguard Worker       };
1068*bbecb9d1SAndroid Build Coastguard Worker       ret = vtest_block_write(ctx->out_fd, resp_buf, sizeof(resp_buf));
1069*bbecb9d1SAndroid Build Coastguard Worker       if (ret < 0) {
1070*bbecb9d1SAndroid Build Coastguard Worker          vtest_unref_resource(res);
1071*bbecb9d1SAndroid Build Coastguard Worker          return ret;
1072*bbecb9d1SAndroid Build Coastguard Worker       }
1073*bbecb9d1SAndroid Build Coastguard Worker    }
1074*bbecb9d1SAndroid Build Coastguard Worker 
1075*bbecb9d1SAndroid Build Coastguard Worker    /* no shm for v1 resources or v2 multi-sample resources */
1076*bbecb9d1SAndroid Build Coastguard Worker    if (shm_size) {
1077*bbecb9d1SAndroid Build Coastguard Worker       int fd;
1078*bbecb9d1SAndroid Build Coastguard Worker 
1079*bbecb9d1SAndroid Build Coastguard Worker       fd = vtest_create_resource_setup_shm(res, shm_size);
1080*bbecb9d1SAndroid Build Coastguard Worker       if (fd < 0) {
1081*bbecb9d1SAndroid Build Coastguard Worker          vtest_unref_resource(res);
1082*bbecb9d1SAndroid Build Coastguard Worker          return -ENOMEM;
1083*bbecb9d1SAndroid Build Coastguard Worker       }
1084*bbecb9d1SAndroid Build Coastguard Worker 
1085*bbecb9d1SAndroid Build Coastguard Worker       ret = vtest_send_fd(ctx->out_fd, fd);
1086*bbecb9d1SAndroid Build Coastguard Worker       if (ret < 0) {
1087*bbecb9d1SAndroid Build Coastguard Worker          close(fd);
1088*bbecb9d1SAndroid Build Coastguard Worker          vtest_unref_resource(res);
1089*bbecb9d1SAndroid Build Coastguard Worker          return report_failed_call("vtest_send_fd", ret);
1090*bbecb9d1SAndroid Build Coastguard Worker       }
1091*bbecb9d1SAndroid Build Coastguard Worker 
1092*bbecb9d1SAndroid Build Coastguard Worker       /* Closing the file descriptor does not unmap the region. */
1093*bbecb9d1SAndroid Build Coastguard Worker       close(fd);
1094*bbecb9d1SAndroid Build Coastguard Worker 
1095*bbecb9d1SAndroid Build Coastguard Worker       virgl_renderer_resource_attach_iov(res->res_id, &res->iov, 1);
1096*bbecb9d1SAndroid Build Coastguard Worker    }
1097*bbecb9d1SAndroid Build Coastguard Worker 
1098*bbecb9d1SAndroid Build Coastguard Worker    util_hash_table_set(ctx->resource_table, intptr_to_pointer(res->res_id), res);
1099*bbecb9d1SAndroid Build Coastguard Worker 
1100*bbecb9d1SAndroid Build Coastguard Worker    return 0;
1101*bbecb9d1SAndroid Build Coastguard Worker }
1102*bbecb9d1SAndroid Build Coastguard Worker 
vtest_create_resource(UNUSED uint32_t length_dw)1103*bbecb9d1SAndroid Build Coastguard Worker int vtest_create_resource(UNUSED uint32_t length_dw)
1104*bbecb9d1SAndroid Build Coastguard Worker {
1105*bbecb9d1SAndroid Build Coastguard Worker    struct vtest_context *ctx = vtest_get_current_context();
1106*bbecb9d1SAndroid Build Coastguard Worker    struct virgl_renderer_resource_create_args args;
1107*bbecb9d1SAndroid Build Coastguard Worker    int ret;
1108*bbecb9d1SAndroid Build Coastguard Worker 
1109*bbecb9d1SAndroid Build Coastguard Worker    ret = vtest_create_resource_decode_args(ctx, &args);
1110*bbecb9d1SAndroid Build Coastguard Worker    if (ret < 0) {
1111*bbecb9d1SAndroid Build Coastguard Worker       return ret;
1112*bbecb9d1SAndroid Build Coastguard Worker    }
1113*bbecb9d1SAndroid Build Coastguard Worker 
1114*bbecb9d1SAndroid Build Coastguard Worker    return vtest_create_resource_internal(ctx, VCMD_RESOURCE_CREATE, &args, 0);
1115*bbecb9d1SAndroid Build Coastguard Worker }
1116*bbecb9d1SAndroid Build Coastguard Worker 
vtest_create_resource2(UNUSED uint32_t length_dw)1117*bbecb9d1SAndroid Build Coastguard Worker int vtest_create_resource2(UNUSED uint32_t length_dw)
1118*bbecb9d1SAndroid Build Coastguard Worker {
1119*bbecb9d1SAndroid Build Coastguard Worker    struct vtest_context *ctx = vtest_get_current_context();
1120*bbecb9d1SAndroid Build Coastguard Worker    struct virgl_renderer_resource_create_args args;
1121*bbecb9d1SAndroid Build Coastguard Worker    size_t shm_size;
1122*bbecb9d1SAndroid Build Coastguard Worker    int ret;
1123*bbecb9d1SAndroid Build Coastguard Worker 
1124*bbecb9d1SAndroid Build Coastguard Worker    ret = vtest_create_resource_decode_args2(ctx, &args, &shm_size);
1125*bbecb9d1SAndroid Build Coastguard Worker    if (ret < 0) {
1126*bbecb9d1SAndroid Build Coastguard Worker       return ret;
1127*bbecb9d1SAndroid Build Coastguard Worker    }
1128*bbecb9d1SAndroid Build Coastguard Worker 
1129*bbecb9d1SAndroid Build Coastguard Worker    return vtest_create_resource_internal(ctx, VCMD_RESOURCE_CREATE2, &args, shm_size);
1130*bbecb9d1SAndroid Build Coastguard Worker }
1131*bbecb9d1SAndroid Build Coastguard Worker 
vtest_resource_create_blob(UNUSED uint32_t length_dw)1132*bbecb9d1SAndroid Build Coastguard Worker int vtest_resource_create_blob(UNUSED uint32_t length_dw)
1133*bbecb9d1SAndroid Build Coastguard Worker {
1134*bbecb9d1SAndroid Build Coastguard Worker    struct vtest_context *ctx = vtest_get_current_context();
1135*bbecb9d1SAndroid Build Coastguard Worker    uint32_t res_create_blob_buf[VCMD_RES_CREATE_BLOB_SIZE];
1136*bbecb9d1SAndroid Build Coastguard Worker    uint32_t resp_buf[VTEST_HDR_SIZE + 1];
1137*bbecb9d1SAndroid Build Coastguard Worker    struct virgl_renderer_resource_create_blob_args args;
1138*bbecb9d1SAndroid Build Coastguard Worker    struct vtest_resource *res;
1139*bbecb9d1SAndroid Build Coastguard Worker    int fd;
1140*bbecb9d1SAndroid Build Coastguard Worker    int ret;
1141*bbecb9d1SAndroid Build Coastguard Worker 
1142*bbecb9d1SAndroid Build Coastguard Worker    ret = ctx->input->read(ctx->input, res_create_blob_buf,
1143*bbecb9d1SAndroid Build Coastguard Worker                           sizeof(res_create_blob_buf));
1144*bbecb9d1SAndroid Build Coastguard Worker    if (ret != sizeof(res_create_blob_buf))
1145*bbecb9d1SAndroid Build Coastguard Worker       return -1;
1146*bbecb9d1SAndroid Build Coastguard Worker 
1147*bbecb9d1SAndroid Build Coastguard Worker    memset(&args, 0, sizeof(args));
1148*bbecb9d1SAndroid Build Coastguard Worker    args.blob_mem = res_create_blob_buf[VCMD_RES_CREATE_BLOB_TYPE];
1149*bbecb9d1SAndroid Build Coastguard Worker    args.blob_flags = res_create_blob_buf[VCMD_RES_CREATE_BLOB_FLAGS];
1150*bbecb9d1SAndroid Build Coastguard Worker    args.size = res_create_blob_buf[VCMD_RES_CREATE_BLOB_SIZE_LO];
1151*bbecb9d1SAndroid Build Coastguard Worker    args.size |= (uint64_t)res_create_blob_buf[VCMD_RES_CREATE_BLOB_SIZE_HI] << 32;
1152*bbecb9d1SAndroid Build Coastguard Worker    args.blob_id = res_create_blob_buf[VCMD_RES_CREATE_BLOB_ID_LO];
1153*bbecb9d1SAndroid Build Coastguard Worker    args.blob_id |= (uint64_t)res_create_blob_buf[VCMD_RES_CREATE_BLOB_ID_HI] << 32;
1154*bbecb9d1SAndroid Build Coastguard Worker 
1155*bbecb9d1SAndroid Build Coastguard Worker    res = vtest_new_resource(0);
1156*bbecb9d1SAndroid Build Coastguard Worker    if (!res)
1157*bbecb9d1SAndroid Build Coastguard Worker       return -ENOMEM;
1158*bbecb9d1SAndroid Build Coastguard Worker 
1159*bbecb9d1SAndroid Build Coastguard Worker    args.res_handle = res->res_id;
1160*bbecb9d1SAndroid Build Coastguard Worker    args.ctx_id = ctx->ctx_id;
1161*bbecb9d1SAndroid Build Coastguard Worker 
1162*bbecb9d1SAndroid Build Coastguard Worker    switch (args.blob_mem) {
1163*bbecb9d1SAndroid Build Coastguard Worker    case VIRGL_RENDERER_BLOB_MEM_GUEST:
1164*bbecb9d1SAndroid Build Coastguard Worker    case VIRGL_RENDERER_BLOB_MEM_HOST3D_GUEST:
1165*bbecb9d1SAndroid Build Coastguard Worker       fd = vtest_create_resource_setup_shm(res, args.size);
1166*bbecb9d1SAndroid Build Coastguard Worker       if (fd < 0) {
1167*bbecb9d1SAndroid Build Coastguard Worker          vtest_unref_resource(res);
1168*bbecb9d1SAndroid Build Coastguard Worker          return -ENOMEM;
1169*bbecb9d1SAndroid Build Coastguard Worker       }
1170*bbecb9d1SAndroid Build Coastguard Worker 
1171*bbecb9d1SAndroid Build Coastguard Worker       args.iovecs = &res->iov;
1172*bbecb9d1SAndroid Build Coastguard Worker       args.num_iovs = 1;
1173*bbecb9d1SAndroid Build Coastguard Worker       break;
1174*bbecb9d1SAndroid Build Coastguard Worker    case VIRGL_RENDERER_BLOB_MEM_HOST3D:
1175*bbecb9d1SAndroid Build Coastguard Worker       fd = -1;
1176*bbecb9d1SAndroid Build Coastguard Worker       break;
1177*bbecb9d1SAndroid Build Coastguard Worker    default:
1178*bbecb9d1SAndroid Build Coastguard Worker       vtest_unref_resource(res);
1179*bbecb9d1SAndroid Build Coastguard Worker       return -EINVAL;
1180*bbecb9d1SAndroid Build Coastguard Worker    }
1181*bbecb9d1SAndroid Build Coastguard Worker 
1182*bbecb9d1SAndroid Build Coastguard Worker    ret = virgl_renderer_resource_create_blob(&args);
1183*bbecb9d1SAndroid Build Coastguard Worker    if (ret) {
1184*bbecb9d1SAndroid Build Coastguard Worker       if (fd >= 0)
1185*bbecb9d1SAndroid Build Coastguard Worker          close(fd);
1186*bbecb9d1SAndroid Build Coastguard Worker       vtest_unref_resource(res);
1187*bbecb9d1SAndroid Build Coastguard Worker       return report_failed_call("virgl_renderer_resource_create_blob", ret);
1188*bbecb9d1SAndroid Build Coastguard Worker    }
1189*bbecb9d1SAndroid Build Coastguard Worker 
1190*bbecb9d1SAndroid Build Coastguard Worker    /* export blob */
1191*bbecb9d1SAndroid Build Coastguard Worker    if (args.blob_mem == VIRGL_RENDERER_BLOB_MEM_HOST3D) {
1192*bbecb9d1SAndroid Build Coastguard Worker       uint32_t fd_type;
1193*bbecb9d1SAndroid Build Coastguard Worker       ret = virgl_renderer_resource_export_blob(res->res_id, &fd_type, &fd);
1194*bbecb9d1SAndroid Build Coastguard Worker       if (ret) {
1195*bbecb9d1SAndroid Build Coastguard Worker          vtest_unref_resource(res);
1196*bbecb9d1SAndroid Build Coastguard Worker          return report_failed_call("virgl_renderer_resource_export_blob", ret);
1197*bbecb9d1SAndroid Build Coastguard Worker       }
1198*bbecb9d1SAndroid Build Coastguard Worker       if (fd_type != VIRGL_RENDERER_BLOB_FD_TYPE_DMABUF &&
1199*bbecb9d1SAndroid Build Coastguard Worker           fd_type != VIRGL_RENDERER_BLOB_FD_TYPE_SHM) {
1200*bbecb9d1SAndroid Build Coastguard Worker          close(fd);
1201*bbecb9d1SAndroid Build Coastguard Worker          vtest_unref_resource(res);
1202*bbecb9d1SAndroid Build Coastguard Worker          return report_failed_call("virgl_renderer_resource_export_blob", -EINVAL);
1203*bbecb9d1SAndroid Build Coastguard Worker       }
1204*bbecb9d1SAndroid Build Coastguard Worker    }
1205*bbecb9d1SAndroid Build Coastguard Worker 
1206*bbecb9d1SAndroid Build Coastguard Worker    virgl_renderer_ctx_attach_resource(ctx->ctx_id, res->res_id);
1207*bbecb9d1SAndroid Build Coastguard Worker 
1208*bbecb9d1SAndroid Build Coastguard Worker    resp_buf[VTEST_CMD_LEN] = 1;
1209*bbecb9d1SAndroid Build Coastguard Worker    resp_buf[VTEST_CMD_ID] = VCMD_RESOURCE_CREATE_BLOB;
1210*bbecb9d1SAndroid Build Coastguard Worker    resp_buf[VTEST_CMD_DATA_START] = res->res_id;
1211*bbecb9d1SAndroid Build Coastguard Worker    ret = vtest_block_write(ctx->out_fd, resp_buf, sizeof(resp_buf));
1212*bbecb9d1SAndroid Build Coastguard Worker    if (ret < 0) {
1213*bbecb9d1SAndroid Build Coastguard Worker       close(fd);
1214*bbecb9d1SAndroid Build Coastguard Worker       vtest_unref_resource(res);
1215*bbecb9d1SAndroid Build Coastguard Worker       return ret;
1216*bbecb9d1SAndroid Build Coastguard Worker    }
1217*bbecb9d1SAndroid Build Coastguard Worker 
1218*bbecb9d1SAndroid Build Coastguard Worker    ret = vtest_send_fd(ctx->out_fd, fd);
1219*bbecb9d1SAndroid Build Coastguard Worker    if (ret < 0) {
1220*bbecb9d1SAndroid Build Coastguard Worker       close(fd);
1221*bbecb9d1SAndroid Build Coastguard Worker       vtest_unref_resource(res);
1222*bbecb9d1SAndroid Build Coastguard Worker       return report_failed_call("vtest_send_fd", ret);
1223*bbecb9d1SAndroid Build Coastguard Worker    }
1224*bbecb9d1SAndroid Build Coastguard Worker 
1225*bbecb9d1SAndroid Build Coastguard Worker    /* Closing the file descriptor does not unmap the region. */
1226*bbecb9d1SAndroid Build Coastguard Worker    close(fd);
1227*bbecb9d1SAndroid Build Coastguard Worker 
1228*bbecb9d1SAndroid Build Coastguard Worker    util_hash_table_set(ctx->resource_table, intptr_to_pointer(res->res_id), res);
1229*bbecb9d1SAndroid Build Coastguard Worker 
1230*bbecb9d1SAndroid Build Coastguard Worker    return 0;
1231*bbecb9d1SAndroid Build Coastguard Worker }
1232*bbecb9d1SAndroid Build Coastguard Worker 
vtest_resource_unref(UNUSED uint32_t length_dw)1233*bbecb9d1SAndroid Build Coastguard Worker int vtest_resource_unref(UNUSED uint32_t length_dw)
1234*bbecb9d1SAndroid Build Coastguard Worker {
1235*bbecb9d1SAndroid Build Coastguard Worker    struct vtest_context *ctx = vtest_get_current_context();
1236*bbecb9d1SAndroid Build Coastguard Worker    uint32_t res_unref_buf[VCMD_RES_UNREF_SIZE];
1237*bbecb9d1SAndroid Build Coastguard Worker    int ret;
1238*bbecb9d1SAndroid Build Coastguard Worker    uint32_t handle;
1239*bbecb9d1SAndroid Build Coastguard Worker 
1240*bbecb9d1SAndroid Build Coastguard Worker    ret = ctx->input->read(ctx->input, &res_unref_buf,
1241*bbecb9d1SAndroid Build Coastguard Worker                           sizeof(res_unref_buf));
1242*bbecb9d1SAndroid Build Coastguard Worker    if (ret != sizeof(res_unref_buf)) {
1243*bbecb9d1SAndroid Build Coastguard Worker       return -1;
1244*bbecb9d1SAndroid Build Coastguard Worker    }
1245*bbecb9d1SAndroid Build Coastguard Worker 
1246*bbecb9d1SAndroid Build Coastguard Worker    handle = res_unref_buf[VCMD_RES_UNREF_RES_HANDLE];
1247*bbecb9d1SAndroid Build Coastguard Worker    util_hash_table_remove(ctx->resource_table, intptr_to_pointer(handle));
1248*bbecb9d1SAndroid Build Coastguard Worker 
1249*bbecb9d1SAndroid Build Coastguard Worker    return 0;
1250*bbecb9d1SAndroid Build Coastguard Worker }
1251*bbecb9d1SAndroid Build Coastguard Worker 
vtest_submit_cmd(uint32_t length_dw)1252*bbecb9d1SAndroid Build Coastguard Worker int vtest_submit_cmd(uint32_t length_dw)
1253*bbecb9d1SAndroid Build Coastguard Worker {
1254*bbecb9d1SAndroid Build Coastguard Worker    struct vtest_context *ctx = vtest_get_current_context();
1255*bbecb9d1SAndroid Build Coastguard Worker    uint32_t *cbuf;
1256*bbecb9d1SAndroid Build Coastguard Worker    int ret;
1257*bbecb9d1SAndroid Build Coastguard Worker 
1258*bbecb9d1SAndroid Build Coastguard Worker    if (length_dw > renderer.max_length / 4) {
1259*bbecb9d1SAndroid Build Coastguard Worker       return -1;
1260*bbecb9d1SAndroid Build Coastguard Worker    }
1261*bbecb9d1SAndroid Build Coastguard Worker 
1262*bbecb9d1SAndroid Build Coastguard Worker    cbuf = malloc(length_dw * 4);
1263*bbecb9d1SAndroid Build Coastguard Worker    if (!cbuf) {
1264*bbecb9d1SAndroid Build Coastguard Worker       return -1;
1265*bbecb9d1SAndroid Build Coastguard Worker    }
1266*bbecb9d1SAndroid Build Coastguard Worker 
1267*bbecb9d1SAndroid Build Coastguard Worker    ret = ctx->input->read(ctx->input, cbuf, length_dw * 4);
1268*bbecb9d1SAndroid Build Coastguard Worker    if (ret != (int)length_dw * 4) {
1269*bbecb9d1SAndroid Build Coastguard Worker       free(cbuf);
1270*bbecb9d1SAndroid Build Coastguard Worker       return -1;
1271*bbecb9d1SAndroid Build Coastguard Worker    }
1272*bbecb9d1SAndroid Build Coastguard Worker 
1273*bbecb9d1SAndroid Build Coastguard Worker    ret = virgl_renderer_submit_cmd(cbuf, ctx->ctx_id, length_dw);
1274*bbecb9d1SAndroid Build Coastguard Worker 
1275*bbecb9d1SAndroid Build Coastguard Worker    free(cbuf);
1276*bbecb9d1SAndroid Build Coastguard Worker    if (ret)
1277*bbecb9d1SAndroid Build Coastguard Worker       return -1;
1278*bbecb9d1SAndroid Build Coastguard Worker 
1279*bbecb9d1SAndroid Build Coastguard Worker    vtest_create_implicit_fence(&renderer);
1280*bbecb9d1SAndroid Build Coastguard Worker    return 0;
1281*bbecb9d1SAndroid Build Coastguard Worker }
1282*bbecb9d1SAndroid Build Coastguard Worker 
1283*bbecb9d1SAndroid Build Coastguard Worker struct vtest_transfer_args {
1284*bbecb9d1SAndroid Build Coastguard Worker    uint32_t handle;
1285*bbecb9d1SAndroid Build Coastguard Worker    uint32_t level;
1286*bbecb9d1SAndroid Build Coastguard Worker    uint32_t stride;
1287*bbecb9d1SAndroid Build Coastguard Worker    uint32_t layer_stride;
1288*bbecb9d1SAndroid Build Coastguard Worker    struct virgl_box box;
1289*bbecb9d1SAndroid Build Coastguard Worker    uint32_t offset;
1290*bbecb9d1SAndroid Build Coastguard Worker };
1291*bbecb9d1SAndroid Build Coastguard Worker 
vtest_transfer_decode_args(struct vtest_context * ctx,struct vtest_transfer_args * args,uint32_t * data_size)1292*bbecb9d1SAndroid Build Coastguard Worker static int vtest_transfer_decode_args(struct vtest_context *ctx,
1293*bbecb9d1SAndroid Build Coastguard Worker                                       struct vtest_transfer_args *args,
1294*bbecb9d1SAndroid Build Coastguard Worker                                       uint32_t *data_size)
1295*bbecb9d1SAndroid Build Coastguard Worker {
1296*bbecb9d1SAndroid Build Coastguard Worker    uint32_t thdr_buf[VCMD_TRANSFER_HDR_SIZE];
1297*bbecb9d1SAndroid Build Coastguard Worker    int ret;
1298*bbecb9d1SAndroid Build Coastguard Worker 
1299*bbecb9d1SAndroid Build Coastguard Worker    ret = ctx->input->read(ctx->input, thdr_buf, sizeof(thdr_buf));
1300*bbecb9d1SAndroid Build Coastguard Worker    if (ret != sizeof(thdr_buf)) {
1301*bbecb9d1SAndroid Build Coastguard Worker       return -1;
1302*bbecb9d1SAndroid Build Coastguard Worker    }
1303*bbecb9d1SAndroid Build Coastguard Worker 
1304*bbecb9d1SAndroid Build Coastguard Worker    args->handle = thdr_buf[VCMD_TRANSFER_RES_HANDLE];
1305*bbecb9d1SAndroid Build Coastguard Worker    args->level = thdr_buf[VCMD_TRANSFER_LEVEL];
1306*bbecb9d1SAndroid Build Coastguard Worker    args->stride = thdr_buf[VCMD_TRANSFER_STRIDE];
1307*bbecb9d1SAndroid Build Coastguard Worker    args->layer_stride = thdr_buf[VCMD_TRANSFER_LAYER_STRIDE];
1308*bbecb9d1SAndroid Build Coastguard Worker    args->box.x = thdr_buf[VCMD_TRANSFER_X];
1309*bbecb9d1SAndroid Build Coastguard Worker    args->box.y = thdr_buf[VCMD_TRANSFER_Y];
1310*bbecb9d1SAndroid Build Coastguard Worker    args->box.z = thdr_buf[VCMD_TRANSFER_Z];
1311*bbecb9d1SAndroid Build Coastguard Worker    args->box.w = thdr_buf[VCMD_TRANSFER_WIDTH];
1312*bbecb9d1SAndroid Build Coastguard Worker    args->box.h = thdr_buf[VCMD_TRANSFER_HEIGHT];
1313*bbecb9d1SAndroid Build Coastguard Worker    args->box.d = thdr_buf[VCMD_TRANSFER_DEPTH];
1314*bbecb9d1SAndroid Build Coastguard Worker    args->offset = 0;
1315*bbecb9d1SAndroid Build Coastguard Worker 
1316*bbecb9d1SAndroid Build Coastguard Worker    *data_size = thdr_buf[VCMD_TRANSFER_DATA_SIZE];
1317*bbecb9d1SAndroid Build Coastguard Worker 
1318*bbecb9d1SAndroid Build Coastguard Worker    if (*data_size > renderer.max_length) {
1319*bbecb9d1SAndroid Build Coastguard Worker       return -ENOMEM;
1320*bbecb9d1SAndroid Build Coastguard Worker    }
1321*bbecb9d1SAndroid Build Coastguard Worker 
1322*bbecb9d1SAndroid Build Coastguard Worker    return 0;
1323*bbecb9d1SAndroid Build Coastguard Worker }
1324*bbecb9d1SAndroid Build Coastguard Worker 
vtest_transfer_decode_args2(struct vtest_context * ctx,struct vtest_transfer_args * args)1325*bbecb9d1SAndroid Build Coastguard Worker static int vtest_transfer_decode_args2(struct vtest_context *ctx,
1326*bbecb9d1SAndroid Build Coastguard Worker                                        struct vtest_transfer_args *args)
1327*bbecb9d1SAndroid Build Coastguard Worker {
1328*bbecb9d1SAndroid Build Coastguard Worker    uint32_t thdr_buf[VCMD_TRANSFER2_HDR_SIZE];
1329*bbecb9d1SAndroid Build Coastguard Worker    int ret;
1330*bbecb9d1SAndroid Build Coastguard Worker 
1331*bbecb9d1SAndroid Build Coastguard Worker    ret = ctx->input->read(ctx->input, thdr_buf, sizeof(thdr_buf));
1332*bbecb9d1SAndroid Build Coastguard Worker    if (ret != sizeof(thdr_buf)) {
1333*bbecb9d1SAndroid Build Coastguard Worker       return -1;
1334*bbecb9d1SAndroid Build Coastguard Worker    }
1335*bbecb9d1SAndroid Build Coastguard Worker 
1336*bbecb9d1SAndroid Build Coastguard Worker    args->handle = thdr_buf[VCMD_TRANSFER2_RES_HANDLE];
1337*bbecb9d1SAndroid Build Coastguard Worker    args->level = thdr_buf[VCMD_TRANSFER2_LEVEL];
1338*bbecb9d1SAndroid Build Coastguard Worker    args->stride = 0;
1339*bbecb9d1SAndroid Build Coastguard Worker    args->layer_stride = 0;
1340*bbecb9d1SAndroid Build Coastguard Worker    args->box.x = thdr_buf[VCMD_TRANSFER2_X];
1341*bbecb9d1SAndroid Build Coastguard Worker    args->box.y = thdr_buf[VCMD_TRANSFER2_Y];
1342*bbecb9d1SAndroid Build Coastguard Worker    args->box.z = thdr_buf[VCMD_TRANSFER2_Z];
1343*bbecb9d1SAndroid Build Coastguard Worker    args->box.w = thdr_buf[VCMD_TRANSFER2_WIDTH];
1344*bbecb9d1SAndroid Build Coastguard Worker    args->box.h = thdr_buf[VCMD_TRANSFER2_HEIGHT];
1345*bbecb9d1SAndroid Build Coastguard Worker    args->box.d = thdr_buf[VCMD_TRANSFER2_DEPTH];
1346*bbecb9d1SAndroid Build Coastguard Worker    args->offset = thdr_buf[VCMD_TRANSFER2_OFFSET];
1347*bbecb9d1SAndroid Build Coastguard Worker 
1348*bbecb9d1SAndroid Build Coastguard Worker    return 0;
1349*bbecb9d1SAndroid Build Coastguard Worker }
1350*bbecb9d1SAndroid Build Coastguard Worker 
vtest_transfer_get_internal(struct vtest_context * ctx,struct vtest_transfer_args * args,uint32_t data_size,bool do_transfer)1351*bbecb9d1SAndroid Build Coastguard Worker static int vtest_transfer_get_internal(struct vtest_context *ctx,
1352*bbecb9d1SAndroid Build Coastguard Worker                                        struct vtest_transfer_args *args,
1353*bbecb9d1SAndroid Build Coastguard Worker                                        uint32_t data_size,
1354*bbecb9d1SAndroid Build Coastguard Worker                                        bool do_transfer)
1355*bbecb9d1SAndroid Build Coastguard Worker {
1356*bbecb9d1SAndroid Build Coastguard Worker    struct vtest_resource *res;
1357*bbecb9d1SAndroid Build Coastguard Worker    struct iovec data_iov;
1358*bbecb9d1SAndroid Build Coastguard Worker    int ret = 0;
1359*bbecb9d1SAndroid Build Coastguard Worker 
1360*bbecb9d1SAndroid Build Coastguard Worker    res = util_hash_table_get(ctx->resource_table,
1361*bbecb9d1SAndroid Build Coastguard Worker                              intptr_to_pointer(args->handle));
1362*bbecb9d1SAndroid Build Coastguard Worker    if (!res) {
1363*bbecb9d1SAndroid Build Coastguard Worker       return report_failed_call("util_hash_table_get", -ESRCH);
1364*bbecb9d1SAndroid Build Coastguard Worker    }
1365*bbecb9d1SAndroid Build Coastguard Worker 
1366*bbecb9d1SAndroid Build Coastguard Worker    if (data_size) {
1367*bbecb9d1SAndroid Build Coastguard Worker       data_iov.iov_len = data_size;
1368*bbecb9d1SAndroid Build Coastguard Worker       data_iov.iov_base = malloc(data_size);
1369*bbecb9d1SAndroid Build Coastguard Worker       if (!data_iov.iov_base) {
1370*bbecb9d1SAndroid Build Coastguard Worker          return -ENOMEM;
1371*bbecb9d1SAndroid Build Coastguard Worker       }
1372*bbecb9d1SAndroid Build Coastguard Worker    } else {
1373*bbecb9d1SAndroid Build Coastguard Worker       if (args->offset >= res->iov.iov_len) {
1374*bbecb9d1SAndroid Build Coastguard Worker          return report_failure("offset larger then length of backing store", -EFAULT);
1375*bbecb9d1SAndroid Build Coastguard Worker       }
1376*bbecb9d1SAndroid Build Coastguard Worker    }
1377*bbecb9d1SAndroid Build Coastguard Worker 
1378*bbecb9d1SAndroid Build Coastguard Worker    if (do_transfer) {
1379*bbecb9d1SAndroid Build Coastguard Worker       ret = virgl_renderer_transfer_read_iov(res->res_id,
1380*bbecb9d1SAndroid Build Coastguard Worker                                              ctx->ctx_id,
1381*bbecb9d1SAndroid Build Coastguard Worker                                              args->level,
1382*bbecb9d1SAndroid Build Coastguard Worker                                              args->stride,
1383*bbecb9d1SAndroid Build Coastguard Worker                                              args->layer_stride,
1384*bbecb9d1SAndroid Build Coastguard Worker                                              &args->box,
1385*bbecb9d1SAndroid Build Coastguard Worker                                              args->offset,
1386*bbecb9d1SAndroid Build Coastguard Worker                                              data_size ? &data_iov : NULL,
1387*bbecb9d1SAndroid Build Coastguard Worker                                              data_size ? 1 : 0);
1388*bbecb9d1SAndroid Build Coastguard Worker       if (ret) {
1389*bbecb9d1SAndroid Build Coastguard Worker          report_failed_call("virgl_renderer_transfer_read_iov", ret);
1390*bbecb9d1SAndroid Build Coastguard Worker       }
1391*bbecb9d1SAndroid Build Coastguard Worker    } else if (data_size) {
1392*bbecb9d1SAndroid Build Coastguard Worker       memset(data_iov.iov_base, 0, data_iov.iov_len);
1393*bbecb9d1SAndroid Build Coastguard Worker    }
1394*bbecb9d1SAndroid Build Coastguard Worker 
1395*bbecb9d1SAndroid Build Coastguard Worker    if (data_size) {
1396*bbecb9d1SAndroid Build Coastguard Worker       ret = vtest_block_write(ctx->out_fd, data_iov.iov_base, data_iov.iov_len);
1397*bbecb9d1SAndroid Build Coastguard Worker       if (ret > 0)
1398*bbecb9d1SAndroid Build Coastguard Worker          ret = 0;
1399*bbecb9d1SAndroid Build Coastguard Worker 
1400*bbecb9d1SAndroid Build Coastguard Worker       free(data_iov.iov_base);
1401*bbecb9d1SAndroid Build Coastguard Worker    }
1402*bbecb9d1SAndroid Build Coastguard Worker 
1403*bbecb9d1SAndroid Build Coastguard Worker    return ret;
1404*bbecb9d1SAndroid Build Coastguard Worker }
1405*bbecb9d1SAndroid Build Coastguard Worker 
vtest_transfer_put_internal(struct vtest_context * ctx,struct vtest_transfer_args * args,uint32_t data_size,bool do_transfer)1406*bbecb9d1SAndroid Build Coastguard Worker static int vtest_transfer_put_internal(struct vtest_context *ctx,
1407*bbecb9d1SAndroid Build Coastguard Worker                                        struct vtest_transfer_args *args,
1408*bbecb9d1SAndroid Build Coastguard Worker                                        uint32_t data_size,
1409*bbecb9d1SAndroid Build Coastguard Worker                                        bool do_transfer)
1410*bbecb9d1SAndroid Build Coastguard Worker {
1411*bbecb9d1SAndroid Build Coastguard Worker    struct vtest_resource *res;
1412*bbecb9d1SAndroid Build Coastguard Worker    struct iovec data_iov;
1413*bbecb9d1SAndroid Build Coastguard Worker    int ret = 0;
1414*bbecb9d1SAndroid Build Coastguard Worker 
1415*bbecb9d1SAndroid Build Coastguard Worker    res = util_hash_table_get(ctx->resource_table,
1416*bbecb9d1SAndroid Build Coastguard Worker                              intptr_to_pointer(args->handle));
1417*bbecb9d1SAndroid Build Coastguard Worker    if (!res) {
1418*bbecb9d1SAndroid Build Coastguard Worker       return report_failed_call("util_hash_table_get", -ESRCH);
1419*bbecb9d1SAndroid Build Coastguard Worker    }
1420*bbecb9d1SAndroid Build Coastguard Worker 
1421*bbecb9d1SAndroid Build Coastguard Worker    if (data_size) {
1422*bbecb9d1SAndroid Build Coastguard Worker       data_iov.iov_len = data_size;
1423*bbecb9d1SAndroid Build Coastguard Worker       data_iov.iov_base = malloc(data_size);
1424*bbecb9d1SAndroid Build Coastguard Worker       if (!data_iov.iov_base) {
1425*bbecb9d1SAndroid Build Coastguard Worker          return -ENOMEM;
1426*bbecb9d1SAndroid Build Coastguard Worker       }
1427*bbecb9d1SAndroid Build Coastguard Worker 
1428*bbecb9d1SAndroid Build Coastguard Worker       ret = ctx->input->read(ctx->input, data_iov.iov_base, data_iov.iov_len);
1429*bbecb9d1SAndroid Build Coastguard Worker       if (ret < 0) {
1430*bbecb9d1SAndroid Build Coastguard Worker          return ret;
1431*bbecb9d1SAndroid Build Coastguard Worker       }
1432*bbecb9d1SAndroid Build Coastguard Worker    }
1433*bbecb9d1SAndroid Build Coastguard Worker 
1434*bbecb9d1SAndroid Build Coastguard Worker    if (do_transfer) {
1435*bbecb9d1SAndroid Build Coastguard Worker       ret = virgl_renderer_transfer_write_iov(res->res_id,
1436*bbecb9d1SAndroid Build Coastguard Worker                                               ctx->ctx_id,
1437*bbecb9d1SAndroid Build Coastguard Worker                                               args->level,
1438*bbecb9d1SAndroid Build Coastguard Worker                                               args->stride,
1439*bbecb9d1SAndroid Build Coastguard Worker                                               args->layer_stride,
1440*bbecb9d1SAndroid Build Coastguard Worker                                               &args->box,
1441*bbecb9d1SAndroid Build Coastguard Worker                                               args->offset,
1442*bbecb9d1SAndroid Build Coastguard Worker                                               data_size ? &data_iov : NULL,
1443*bbecb9d1SAndroid Build Coastguard Worker                                               data_size ? 1 : 0);
1444*bbecb9d1SAndroid Build Coastguard Worker       if (ret) {
1445*bbecb9d1SAndroid Build Coastguard Worker          report_failed_call("virgl_renderer_transfer_write_iov", ret);
1446*bbecb9d1SAndroid Build Coastguard Worker       }
1447*bbecb9d1SAndroid Build Coastguard Worker    }
1448*bbecb9d1SAndroid Build Coastguard Worker 
1449*bbecb9d1SAndroid Build Coastguard Worker    if (data_size) {
1450*bbecb9d1SAndroid Build Coastguard Worker       free(data_iov.iov_base);
1451*bbecb9d1SAndroid Build Coastguard Worker    }
1452*bbecb9d1SAndroid Build Coastguard Worker 
1453*bbecb9d1SAndroid Build Coastguard Worker    return ret;
1454*bbecb9d1SAndroid Build Coastguard Worker }
1455*bbecb9d1SAndroid Build Coastguard Worker 
vtest_transfer_get(UNUSED uint32_t length_dw)1456*bbecb9d1SAndroid Build Coastguard Worker int vtest_transfer_get(UNUSED uint32_t length_dw)
1457*bbecb9d1SAndroid Build Coastguard Worker {
1458*bbecb9d1SAndroid Build Coastguard Worker    struct vtest_context *ctx = vtest_get_current_context();
1459*bbecb9d1SAndroid Build Coastguard Worker    int ret;
1460*bbecb9d1SAndroid Build Coastguard Worker    struct vtest_transfer_args args;
1461*bbecb9d1SAndroid Build Coastguard Worker    uint32_t data_size;
1462*bbecb9d1SAndroid Build Coastguard Worker 
1463*bbecb9d1SAndroid Build Coastguard Worker    ret = vtest_transfer_decode_args(ctx, &args, &data_size);
1464*bbecb9d1SAndroid Build Coastguard Worker    if (ret < 0) {
1465*bbecb9d1SAndroid Build Coastguard Worker       return ret;
1466*bbecb9d1SAndroid Build Coastguard Worker    }
1467*bbecb9d1SAndroid Build Coastguard Worker 
1468*bbecb9d1SAndroid Build Coastguard Worker    return vtest_transfer_get_internal(ctx, &args, data_size, true);
1469*bbecb9d1SAndroid Build Coastguard Worker }
1470*bbecb9d1SAndroid Build Coastguard Worker 
vtest_transfer_get_nop(UNUSED uint32_t length_dw)1471*bbecb9d1SAndroid Build Coastguard Worker int vtest_transfer_get_nop(UNUSED uint32_t length_dw)
1472*bbecb9d1SAndroid Build Coastguard Worker {
1473*bbecb9d1SAndroid Build Coastguard Worker    struct vtest_context *ctx = vtest_get_current_context();
1474*bbecb9d1SAndroid Build Coastguard Worker    int ret;
1475*bbecb9d1SAndroid Build Coastguard Worker    struct vtest_transfer_args args;
1476*bbecb9d1SAndroid Build Coastguard Worker    uint32_t data_size;
1477*bbecb9d1SAndroid Build Coastguard Worker 
1478*bbecb9d1SAndroid Build Coastguard Worker    ret = vtest_transfer_decode_args(ctx, &args, &data_size);
1479*bbecb9d1SAndroid Build Coastguard Worker    if (ret < 0) {
1480*bbecb9d1SAndroid Build Coastguard Worker       return ret;
1481*bbecb9d1SAndroid Build Coastguard Worker    }
1482*bbecb9d1SAndroid Build Coastguard Worker 
1483*bbecb9d1SAndroid Build Coastguard Worker    return vtest_transfer_get_internal(ctx, &args, data_size, false);
1484*bbecb9d1SAndroid Build Coastguard Worker }
1485*bbecb9d1SAndroid Build Coastguard Worker 
vtest_transfer_put(UNUSED uint32_t length_dw)1486*bbecb9d1SAndroid Build Coastguard Worker int vtest_transfer_put(UNUSED uint32_t length_dw)
1487*bbecb9d1SAndroid Build Coastguard Worker {
1488*bbecb9d1SAndroid Build Coastguard Worker    struct vtest_context *ctx = vtest_get_current_context();
1489*bbecb9d1SAndroid Build Coastguard Worker    int ret;
1490*bbecb9d1SAndroid Build Coastguard Worker    struct vtest_transfer_args args;
1491*bbecb9d1SAndroid Build Coastguard Worker    uint32_t data_size;
1492*bbecb9d1SAndroid Build Coastguard Worker 
1493*bbecb9d1SAndroid Build Coastguard Worker    ret = vtest_transfer_decode_args(ctx, &args, &data_size);
1494*bbecb9d1SAndroid Build Coastguard Worker    if (ret < 0) {
1495*bbecb9d1SAndroid Build Coastguard Worker       return ret;
1496*bbecb9d1SAndroid Build Coastguard Worker    }
1497*bbecb9d1SAndroid Build Coastguard Worker 
1498*bbecb9d1SAndroid Build Coastguard Worker    return vtest_transfer_put_internal(ctx, &args, data_size, true);
1499*bbecb9d1SAndroid Build Coastguard Worker }
1500*bbecb9d1SAndroid Build Coastguard Worker 
vtest_transfer_put_nop(UNUSED uint32_t length_dw)1501*bbecb9d1SAndroid Build Coastguard Worker int vtest_transfer_put_nop(UNUSED uint32_t length_dw)
1502*bbecb9d1SAndroid Build Coastguard Worker {
1503*bbecb9d1SAndroid Build Coastguard Worker    struct vtest_context *ctx = vtest_get_current_context();
1504*bbecb9d1SAndroid Build Coastguard Worker    int ret;
1505*bbecb9d1SAndroid Build Coastguard Worker    struct vtest_transfer_args args;
1506*bbecb9d1SAndroid Build Coastguard Worker    uint32_t data_size;
1507*bbecb9d1SAndroid Build Coastguard Worker 
1508*bbecb9d1SAndroid Build Coastguard Worker    ret = vtest_transfer_decode_args(ctx, &args, &data_size);
1509*bbecb9d1SAndroid Build Coastguard Worker    if (ret < 0) {
1510*bbecb9d1SAndroid Build Coastguard Worker       return ret;
1511*bbecb9d1SAndroid Build Coastguard Worker    }
1512*bbecb9d1SAndroid Build Coastguard Worker 
1513*bbecb9d1SAndroid Build Coastguard Worker    return vtest_transfer_put_internal(ctx, &args, data_size, false);
1514*bbecb9d1SAndroid Build Coastguard Worker }
1515*bbecb9d1SAndroid Build Coastguard Worker 
vtest_transfer_get2(UNUSED uint32_t length_dw)1516*bbecb9d1SAndroid Build Coastguard Worker int vtest_transfer_get2(UNUSED uint32_t length_dw)
1517*bbecb9d1SAndroid Build Coastguard Worker {
1518*bbecb9d1SAndroid Build Coastguard Worker    struct vtest_context *ctx = vtest_get_current_context();
1519*bbecb9d1SAndroid Build Coastguard Worker    int ret;
1520*bbecb9d1SAndroid Build Coastguard Worker    struct vtest_transfer_args args;
1521*bbecb9d1SAndroid Build Coastguard Worker 
1522*bbecb9d1SAndroid Build Coastguard Worker    ret = vtest_transfer_decode_args2(ctx, &args);
1523*bbecb9d1SAndroid Build Coastguard Worker    if (ret < 0) {
1524*bbecb9d1SAndroid Build Coastguard Worker       return ret;
1525*bbecb9d1SAndroid Build Coastguard Worker    }
1526*bbecb9d1SAndroid Build Coastguard Worker 
1527*bbecb9d1SAndroid Build Coastguard Worker    return vtest_transfer_get_internal(ctx, &args, 0, true);
1528*bbecb9d1SAndroid Build Coastguard Worker }
1529*bbecb9d1SAndroid Build Coastguard Worker 
vtest_transfer_get2_nop(UNUSED uint32_t length_dw)1530*bbecb9d1SAndroid Build Coastguard Worker int vtest_transfer_get2_nop(UNUSED uint32_t length_dw)
1531*bbecb9d1SAndroid Build Coastguard Worker {
1532*bbecb9d1SAndroid Build Coastguard Worker    struct vtest_context *ctx = vtest_get_current_context();
1533*bbecb9d1SAndroid Build Coastguard Worker    int ret;
1534*bbecb9d1SAndroid Build Coastguard Worker    struct vtest_transfer_args args;
1535*bbecb9d1SAndroid Build Coastguard Worker 
1536*bbecb9d1SAndroid Build Coastguard Worker    ret = vtest_transfer_decode_args2(ctx, &args);
1537*bbecb9d1SAndroid Build Coastguard Worker    if (ret < 0) {
1538*bbecb9d1SAndroid Build Coastguard Worker       return ret;
1539*bbecb9d1SAndroid Build Coastguard Worker    }
1540*bbecb9d1SAndroid Build Coastguard Worker 
1541*bbecb9d1SAndroid Build Coastguard Worker    return vtest_transfer_get_internal(ctx, &args, 0, false);
1542*bbecb9d1SAndroid Build Coastguard Worker }
1543*bbecb9d1SAndroid Build Coastguard Worker 
vtest_transfer_put2(UNUSED uint32_t length_dw)1544*bbecb9d1SAndroid Build Coastguard Worker int vtest_transfer_put2(UNUSED uint32_t length_dw)
1545*bbecb9d1SAndroid Build Coastguard Worker {
1546*bbecb9d1SAndroid Build Coastguard Worker    struct vtest_context *ctx = vtest_get_current_context();
1547*bbecb9d1SAndroid Build Coastguard Worker    int ret;
1548*bbecb9d1SAndroid Build Coastguard Worker    struct vtest_transfer_args args;
1549*bbecb9d1SAndroid Build Coastguard Worker 
1550*bbecb9d1SAndroid Build Coastguard Worker    ret = vtest_transfer_decode_args2(ctx, &args);
1551*bbecb9d1SAndroid Build Coastguard Worker    if (ret < 0) {
1552*bbecb9d1SAndroid Build Coastguard Worker       return ret;
1553*bbecb9d1SAndroid Build Coastguard Worker    }
1554*bbecb9d1SAndroid Build Coastguard Worker 
1555*bbecb9d1SAndroid Build Coastguard Worker    return vtest_transfer_put_internal(ctx, &args, 0, true);
1556*bbecb9d1SAndroid Build Coastguard Worker }
1557*bbecb9d1SAndroid Build Coastguard Worker 
vtest_transfer_put2_nop(UNUSED uint32_t length_dw)1558*bbecb9d1SAndroid Build Coastguard Worker int vtest_transfer_put2_nop(UNUSED uint32_t length_dw)
1559*bbecb9d1SAndroid Build Coastguard Worker {
1560*bbecb9d1SAndroid Build Coastguard Worker    struct vtest_context *ctx = vtest_get_current_context();
1561*bbecb9d1SAndroid Build Coastguard Worker    int ret;
1562*bbecb9d1SAndroid Build Coastguard Worker    struct vtest_transfer_args args;
1563*bbecb9d1SAndroid Build Coastguard Worker 
1564*bbecb9d1SAndroid Build Coastguard Worker    ret = vtest_transfer_decode_args2(ctx, &args);
1565*bbecb9d1SAndroid Build Coastguard Worker    if (ret < 0) {
1566*bbecb9d1SAndroid Build Coastguard Worker       return ret;
1567*bbecb9d1SAndroid Build Coastguard Worker    }
1568*bbecb9d1SAndroid Build Coastguard Worker 
1569*bbecb9d1SAndroid Build Coastguard Worker    return vtest_transfer_put_internal(ctx, &args, 0, false);
1570*bbecb9d1SAndroid Build Coastguard Worker }
1571*bbecb9d1SAndroid Build Coastguard Worker 
vtest_resource_busy_wait(UNUSED uint32_t length_dw)1572*bbecb9d1SAndroid Build Coastguard Worker int vtest_resource_busy_wait(UNUSED uint32_t length_dw)
1573*bbecb9d1SAndroid Build Coastguard Worker {
1574*bbecb9d1SAndroid Build Coastguard Worker    struct vtest_context *ctx = vtest_get_current_context();
1575*bbecb9d1SAndroid Build Coastguard Worker    uint32_t bw_buf[VCMD_BUSY_WAIT_SIZE];
1576*bbecb9d1SAndroid Build Coastguard Worker    int ret, fd;
1577*bbecb9d1SAndroid Build Coastguard Worker    int flags;
1578*bbecb9d1SAndroid Build Coastguard Worker    uint32_t hdr_buf[VTEST_HDR_SIZE];
1579*bbecb9d1SAndroid Build Coastguard Worker    uint32_t reply_buf[1];
1580*bbecb9d1SAndroid Build Coastguard Worker    bool busy = false;
1581*bbecb9d1SAndroid Build Coastguard Worker 
1582*bbecb9d1SAndroid Build Coastguard Worker    ret = ctx->input->read(ctx->input, &bw_buf, sizeof(bw_buf));
1583*bbecb9d1SAndroid Build Coastguard Worker    if (ret != sizeof(bw_buf)) {
1584*bbecb9d1SAndroid Build Coastguard Worker       return -1;
1585*bbecb9d1SAndroid Build Coastguard Worker    }
1586*bbecb9d1SAndroid Build Coastguard Worker 
1587*bbecb9d1SAndroid Build Coastguard Worker    /* clients often send VCMD_PING_PROTOCOL_VERSION followed by
1588*bbecb9d1SAndroid Build Coastguard Worker     * VCMD_RESOURCE_BUSY_WAIT with handle 0 to figure out if
1589*bbecb9d1SAndroid Build Coastguard Worker     * VCMD_PING_PROTOCOL_VERSION is supported.  We need to make a special case
1590*bbecb9d1SAndroid Build Coastguard Worker     * for that.
1591*bbecb9d1SAndroid Build Coastguard Worker     */
1592*bbecb9d1SAndroid Build Coastguard Worker    if (!ctx->context_initialized && bw_buf[VCMD_BUSY_WAIT_HANDLE])
1593*bbecb9d1SAndroid Build Coastguard Worker       return -1;
1594*bbecb9d1SAndroid Build Coastguard Worker 
1595*bbecb9d1SAndroid Build Coastguard Worker    /*  handle = bw_buf[VCMD_BUSY_WAIT_HANDLE]; unused as of now */
1596*bbecb9d1SAndroid Build Coastguard Worker    flags = bw_buf[VCMD_BUSY_WAIT_FLAGS];
1597*bbecb9d1SAndroid Build Coastguard Worker 
1598*bbecb9d1SAndroid Build Coastguard Worker    do {
1599*bbecb9d1SAndroid Build Coastguard Worker       busy = renderer.implicit_fence_completed !=
1600*bbecb9d1SAndroid Build Coastguard Worker              renderer.implicit_fence_submitted;
1601*bbecb9d1SAndroid Build Coastguard Worker       if (!busy || !(flags & VCMD_BUSY_WAIT_FLAG_WAIT))
1602*bbecb9d1SAndroid Build Coastguard Worker          break;
1603*bbecb9d1SAndroid Build Coastguard Worker 
1604*bbecb9d1SAndroid Build Coastguard Worker       /* TODO this is bad when there are multiple clients */
1605*bbecb9d1SAndroid Build Coastguard Worker       fd = virgl_renderer_get_poll_fd();
1606*bbecb9d1SAndroid Build Coastguard Worker       if (fd != -1) {
1607*bbecb9d1SAndroid Build Coastguard Worker          vtest_wait_for_fd_read(fd);
1608*bbecb9d1SAndroid Build Coastguard Worker       }
1609*bbecb9d1SAndroid Build Coastguard Worker       virgl_renderer_poll();
1610*bbecb9d1SAndroid Build Coastguard Worker    } while (true);
1611*bbecb9d1SAndroid Build Coastguard Worker 
1612*bbecb9d1SAndroid Build Coastguard Worker    hdr_buf[VTEST_CMD_LEN] = 1;
1613*bbecb9d1SAndroid Build Coastguard Worker    hdr_buf[VTEST_CMD_ID] = VCMD_RESOURCE_BUSY_WAIT;
1614*bbecb9d1SAndroid Build Coastguard Worker    reply_buf[0] = busy ? 1 : 0;
1615*bbecb9d1SAndroid Build Coastguard Worker 
1616*bbecb9d1SAndroid Build Coastguard Worker    ret = vtest_block_write(ctx->out_fd, hdr_buf, sizeof(hdr_buf));
1617*bbecb9d1SAndroid Build Coastguard Worker    if (ret < 0) {
1618*bbecb9d1SAndroid Build Coastguard Worker       return ret;
1619*bbecb9d1SAndroid Build Coastguard Worker    }
1620*bbecb9d1SAndroid Build Coastguard Worker 
1621*bbecb9d1SAndroid Build Coastguard Worker    ret = vtest_block_write(ctx->out_fd, reply_buf, sizeof(reply_buf));
1622*bbecb9d1SAndroid Build Coastguard Worker    if (ret < 0) {
1623*bbecb9d1SAndroid Build Coastguard Worker       return ret;
1624*bbecb9d1SAndroid Build Coastguard Worker    }
1625*bbecb9d1SAndroid Build Coastguard Worker 
1626*bbecb9d1SAndroid Build Coastguard Worker    return 0;
1627*bbecb9d1SAndroid Build Coastguard Worker }
1628*bbecb9d1SAndroid Build Coastguard Worker 
vtest_resource_busy_wait_nop(UNUSED uint32_t length_dw)1629*bbecb9d1SAndroid Build Coastguard Worker int vtest_resource_busy_wait_nop(UNUSED uint32_t length_dw)
1630*bbecb9d1SAndroid Build Coastguard Worker {
1631*bbecb9d1SAndroid Build Coastguard Worker    struct vtest_context *ctx = vtest_get_current_context();
1632*bbecb9d1SAndroid Build Coastguard Worker    uint32_t bw_buf[VCMD_BUSY_WAIT_SIZE];
1633*bbecb9d1SAndroid Build Coastguard Worker    uint32_t reply_buf[VTEST_HDR_SIZE + 1];
1634*bbecb9d1SAndroid Build Coastguard Worker    int ret;
1635*bbecb9d1SAndroid Build Coastguard Worker 
1636*bbecb9d1SAndroid Build Coastguard Worker    ret = ctx->input->read(ctx->input, &bw_buf, sizeof(bw_buf));
1637*bbecb9d1SAndroid Build Coastguard Worker    if (ret != sizeof(bw_buf)) {
1638*bbecb9d1SAndroid Build Coastguard Worker       return -1;
1639*bbecb9d1SAndroid Build Coastguard Worker    }
1640*bbecb9d1SAndroid Build Coastguard Worker 
1641*bbecb9d1SAndroid Build Coastguard Worker    reply_buf[VTEST_CMD_LEN] = 1;
1642*bbecb9d1SAndroid Build Coastguard Worker    reply_buf[VTEST_CMD_ID] = VCMD_RESOURCE_BUSY_WAIT;
1643*bbecb9d1SAndroid Build Coastguard Worker    reply_buf[VTEST_CMD_DATA_START] = 0;
1644*bbecb9d1SAndroid Build Coastguard Worker 
1645*bbecb9d1SAndroid Build Coastguard Worker    ret = vtest_block_write(ctx->out_fd, reply_buf, sizeof(reply_buf));
1646*bbecb9d1SAndroid Build Coastguard Worker    if (ret < 0) {
1647*bbecb9d1SAndroid Build Coastguard Worker       return ret;
1648*bbecb9d1SAndroid Build Coastguard Worker    }
1649*bbecb9d1SAndroid Build Coastguard Worker 
1650*bbecb9d1SAndroid Build Coastguard Worker    return 0;
1651*bbecb9d1SAndroid Build Coastguard Worker }
1652*bbecb9d1SAndroid Build Coastguard Worker 
vtest_poll_resource_busy_wait(void)1653*bbecb9d1SAndroid Build Coastguard Worker void vtest_poll_resource_busy_wait(void)
1654*bbecb9d1SAndroid Build Coastguard Worker {
1655*bbecb9d1SAndroid Build Coastguard Worker    /* poll the implicit fences */
1656*bbecb9d1SAndroid Build Coastguard Worker    virgl_renderer_poll();
1657*bbecb9d1SAndroid Build Coastguard Worker }
1658*bbecb9d1SAndroid Build Coastguard Worker 
vtest_gettime(uint32_t offset_ms)1659*bbecb9d1SAndroid Build Coastguard Worker static uint64_t vtest_gettime(uint32_t offset_ms)
1660*bbecb9d1SAndroid Build Coastguard Worker {
1661*bbecb9d1SAndroid Build Coastguard Worker    const uint64_t ns_per_ms = 1000000;
1662*bbecb9d1SAndroid Build Coastguard Worker    const uint64_t ns_per_s = ns_per_ms * 1000;
1663*bbecb9d1SAndroid Build Coastguard Worker    struct timespec ts;
1664*bbecb9d1SAndroid Build Coastguard Worker    uint64_t ns;
1665*bbecb9d1SAndroid Build Coastguard Worker 
1666*bbecb9d1SAndroid Build Coastguard Worker    if (offset_ms > INT32_MAX)
1667*bbecb9d1SAndroid Build Coastguard Worker       return UINT64_MAX;
1668*bbecb9d1SAndroid Build Coastguard Worker 
1669*bbecb9d1SAndroid Build Coastguard Worker    clock_gettime(CLOCK_MONOTONIC, &ts);
1670*bbecb9d1SAndroid Build Coastguard Worker    ns = ns_per_s * ts.tv_sec + ts.tv_nsec;
1671*bbecb9d1SAndroid Build Coastguard Worker 
1672*bbecb9d1SAndroid Build Coastguard Worker    return ns + ns_per_ms * offset_ms;
1673*bbecb9d1SAndroid Build Coastguard Worker }
1674*bbecb9d1SAndroid Build Coastguard Worker 
write_ready(int fd)1675*bbecb9d1SAndroid Build Coastguard Worker static inline void write_ready(int fd)
1676*bbecb9d1SAndroid Build Coastguard Worker {
1677*bbecb9d1SAndroid Build Coastguard Worker #ifdef __GNUC__
1678*bbecb9d1SAndroid Build Coastguard Worker #  pragma GCC diagnostic push
1679*bbecb9d1SAndroid Build Coastguard Worker #  pragma GCC diagnostic ignored "-Wunused-result"
1680*bbecb9d1SAndroid Build Coastguard Worker #endif
1681*bbecb9d1SAndroid Build Coastguard Worker    static const uint64_t val = 1;
1682*bbecb9d1SAndroid Build Coastguard Worker    write(fd, &val, sizeof(val));
1683*bbecb9d1SAndroid Build Coastguard Worker #ifdef __GNUC__
1684*bbecb9d1SAndroid Build Coastguard Worker #  pragma GCC diagnostic pop
1685*bbecb9d1SAndroid Build Coastguard Worker #endif
1686*bbecb9d1SAndroid Build Coastguard Worker }
1687*bbecb9d1SAndroid Build Coastguard Worker 
1688*bbecb9d1SAndroid Build Coastguard Worker 
1689*bbecb9d1SAndroid Build Coastguard Worker /* TODO this is slow */
vtest_signal_sync(struct vtest_sync * sync,uint64_t value)1690*bbecb9d1SAndroid Build Coastguard Worker static void vtest_signal_sync(struct vtest_sync *sync, uint64_t value)
1691*bbecb9d1SAndroid Build Coastguard Worker {
1692*bbecb9d1SAndroid Build Coastguard Worker    struct vtest_context *ctx;
1693*bbecb9d1SAndroid Build Coastguard Worker    uint64_t now;
1694*bbecb9d1SAndroid Build Coastguard Worker 
1695*bbecb9d1SAndroid Build Coastguard Worker    if (sync->value >= value) {
1696*bbecb9d1SAndroid Build Coastguard Worker       sync->value = value;
1697*bbecb9d1SAndroid Build Coastguard Worker       return;
1698*bbecb9d1SAndroid Build Coastguard Worker    }
1699*bbecb9d1SAndroid Build Coastguard Worker    sync->value = value;
1700*bbecb9d1SAndroid Build Coastguard Worker 
1701*bbecb9d1SAndroid Build Coastguard Worker    now = vtest_gettime(0);
1702*bbecb9d1SAndroid Build Coastguard Worker 
1703*bbecb9d1SAndroid Build Coastguard Worker    LIST_FOR_EACH_ENTRY(ctx, &renderer.active_contexts, head) {
1704*bbecb9d1SAndroid Build Coastguard Worker       struct vtest_sync_wait *wait, *tmp;
1705*bbecb9d1SAndroid Build Coastguard Worker       LIST_FOR_EACH_ENTRY_SAFE(wait, tmp, &ctx->sync_waits, head) {
1706*bbecb9d1SAndroid Build Coastguard Worker          bool is_ready = false;
1707*bbecb9d1SAndroid Build Coastguard Worker          uint32_t i;
1708*bbecb9d1SAndroid Build Coastguard Worker 
1709*bbecb9d1SAndroid Build Coastguard Worker          /* garbage collect */
1710*bbecb9d1SAndroid Build Coastguard Worker          if (wait->valid_before < now) {
1711*bbecb9d1SAndroid Build Coastguard Worker             list_del(&wait->head);
1712*bbecb9d1SAndroid Build Coastguard Worker             vtest_free_sync_wait(wait);
1713*bbecb9d1SAndroid Build Coastguard Worker             continue;
1714*bbecb9d1SAndroid Build Coastguard Worker          }
1715*bbecb9d1SAndroid Build Coastguard Worker 
1716*bbecb9d1SAndroid Build Coastguard Worker          for (i = 0; i < wait->count; i++) {
1717*bbecb9d1SAndroid Build Coastguard Worker             if (wait->syncs[i] != sync || wait->values[i] > value)
1718*bbecb9d1SAndroid Build Coastguard Worker                continue;
1719*bbecb9d1SAndroid Build Coastguard Worker 
1720*bbecb9d1SAndroid Build Coastguard Worker             vtest_unref_sync(wait->syncs[i]);
1721*bbecb9d1SAndroid Build Coastguard Worker             wait->syncs[i] = NULL;
1722*bbecb9d1SAndroid Build Coastguard Worker 
1723*bbecb9d1SAndroid Build Coastguard Worker             wait->signaled_count++;
1724*bbecb9d1SAndroid Build Coastguard Worker             if (wait->signaled_count == wait->count ||
1725*bbecb9d1SAndroid Build Coastguard Worker                 (wait->flags & VCMD_SYNC_WAIT_FLAG_ANY)) {
1726*bbecb9d1SAndroid Build Coastguard Worker                is_ready = true;
1727*bbecb9d1SAndroid Build Coastguard Worker                break;
1728*bbecb9d1SAndroid Build Coastguard Worker             }
1729*bbecb9d1SAndroid Build Coastguard Worker          }
1730*bbecb9d1SAndroid Build Coastguard Worker 
1731*bbecb9d1SAndroid Build Coastguard Worker          if (is_ready) {
1732*bbecb9d1SAndroid Build Coastguard Worker             list_del(&wait->head);
1733*bbecb9d1SAndroid Build Coastguard Worker             write_ready(wait->fd);
1734*bbecb9d1SAndroid Build Coastguard Worker             vtest_free_sync_wait(wait);
1735*bbecb9d1SAndroid Build Coastguard Worker          }
1736*bbecb9d1SAndroid Build Coastguard Worker       }
1737*bbecb9d1SAndroid Build Coastguard Worker    }
1738*bbecb9d1SAndroid Build Coastguard Worker }
1739*bbecb9d1SAndroid Build Coastguard Worker 
vtest_signal_timeline(struct vtest_timeline * timeline,struct vtest_timeline_submit * to_submit)1740*bbecb9d1SAndroid Build Coastguard Worker static void vtest_signal_timeline(struct vtest_timeline *timeline,
1741*bbecb9d1SAndroid Build Coastguard Worker                                   struct vtest_timeline_submit *to_submit)
1742*bbecb9d1SAndroid Build Coastguard Worker {
1743*bbecb9d1SAndroid Build Coastguard Worker    struct vtest_timeline_submit *submit, *tmp;
1744*bbecb9d1SAndroid Build Coastguard Worker 
1745*bbecb9d1SAndroid Build Coastguard Worker    LIST_FOR_EACH_ENTRY_SAFE(submit, tmp, &timeline->submits, head) {
1746*bbecb9d1SAndroid Build Coastguard Worker       uint32_t i;
1747*bbecb9d1SAndroid Build Coastguard Worker 
1748*bbecb9d1SAndroid Build Coastguard Worker       list_del(&submit->head);
1749*bbecb9d1SAndroid Build Coastguard Worker 
1750*bbecb9d1SAndroid Build Coastguard Worker       for (i = 0; i < submit->count; i++) {
1751*bbecb9d1SAndroid Build Coastguard Worker          vtest_signal_sync(submit->syncs[i], submit->values[i]);
1752*bbecb9d1SAndroid Build Coastguard Worker          vtest_unref_sync(submit->syncs[i]);
1753*bbecb9d1SAndroid Build Coastguard Worker       }
1754*bbecb9d1SAndroid Build Coastguard Worker       free(submit);
1755*bbecb9d1SAndroid Build Coastguard Worker 
1756*bbecb9d1SAndroid Build Coastguard Worker       if (submit == to_submit)
1757*bbecb9d1SAndroid Build Coastguard Worker          break;
1758*bbecb9d1SAndroid Build Coastguard Worker    }
1759*bbecb9d1SAndroid Build Coastguard Worker }
1760*bbecb9d1SAndroid Build Coastguard Worker 
vtest_sync_create(UNUSED uint32_t length_dw)1761*bbecb9d1SAndroid Build Coastguard Worker int vtest_sync_create(UNUSED uint32_t length_dw)
1762*bbecb9d1SAndroid Build Coastguard Worker {
1763*bbecb9d1SAndroid Build Coastguard Worker    struct vtest_context *ctx = vtest_get_current_context();
1764*bbecb9d1SAndroid Build Coastguard Worker    uint32_t sync_create_buf[VCMD_SYNC_CREATE_SIZE];
1765*bbecb9d1SAndroid Build Coastguard Worker    uint32_t resp_buf[VTEST_HDR_SIZE + 1];
1766*bbecb9d1SAndroid Build Coastguard Worker    uint64_t value;
1767*bbecb9d1SAndroid Build Coastguard Worker    struct vtest_sync *sync;
1768*bbecb9d1SAndroid Build Coastguard Worker    int ret;
1769*bbecb9d1SAndroid Build Coastguard Worker 
1770*bbecb9d1SAndroid Build Coastguard Worker    ret = ctx->input->read(ctx->input, sync_create_buf, sizeof(sync_create_buf));
1771*bbecb9d1SAndroid Build Coastguard Worker    if (ret != sizeof(sync_create_buf))
1772*bbecb9d1SAndroid Build Coastguard Worker       return -1;
1773*bbecb9d1SAndroid Build Coastguard Worker 
1774*bbecb9d1SAndroid Build Coastguard Worker    value = sync_create_buf[VCMD_SYNC_CREATE_VALUE_LO];
1775*bbecb9d1SAndroid Build Coastguard Worker    value |= (uint64_t)sync_create_buf[VCMD_SYNC_CREATE_VALUE_HI] << 32;
1776*bbecb9d1SAndroid Build Coastguard Worker 
1777*bbecb9d1SAndroid Build Coastguard Worker    sync = vtest_new_sync(value);
1778*bbecb9d1SAndroid Build Coastguard Worker    if (!sync)
1779*bbecb9d1SAndroid Build Coastguard Worker       return -ENOMEM;
1780*bbecb9d1SAndroid Build Coastguard Worker 
1781*bbecb9d1SAndroid Build Coastguard Worker    resp_buf[VTEST_CMD_LEN] = 1;
1782*bbecb9d1SAndroid Build Coastguard Worker    resp_buf[VTEST_CMD_ID] = VCMD_SYNC_CREATE;
1783*bbecb9d1SAndroid Build Coastguard Worker    resp_buf[VTEST_CMD_DATA_START] = sync->sync_id;
1784*bbecb9d1SAndroid Build Coastguard Worker    ret = vtest_block_write(ctx->out_fd, resp_buf, sizeof(resp_buf));
1785*bbecb9d1SAndroid Build Coastguard Worker    if (ret < 0) {
1786*bbecb9d1SAndroid Build Coastguard Worker       vtest_unref_sync(sync);
1787*bbecb9d1SAndroid Build Coastguard Worker       return ret;
1788*bbecb9d1SAndroid Build Coastguard Worker    }
1789*bbecb9d1SAndroid Build Coastguard Worker 
1790*bbecb9d1SAndroid Build Coastguard Worker    util_hash_table_set(ctx->sync_table, intptr_to_pointer(sync->sync_id), sync);
1791*bbecb9d1SAndroid Build Coastguard Worker 
1792*bbecb9d1SAndroid Build Coastguard Worker    return 0;
1793*bbecb9d1SAndroid Build Coastguard Worker }
1794*bbecb9d1SAndroid Build Coastguard Worker 
vtest_sync_unref(UNUSED uint32_t length_dw)1795*bbecb9d1SAndroid Build Coastguard Worker int vtest_sync_unref(UNUSED uint32_t length_dw)
1796*bbecb9d1SAndroid Build Coastguard Worker {
1797*bbecb9d1SAndroid Build Coastguard Worker    struct vtest_context *ctx = vtest_get_current_context();
1798*bbecb9d1SAndroid Build Coastguard Worker    uint32_t sync_unref_buf[VCMD_SYNC_UNREF_SIZE];
1799*bbecb9d1SAndroid Build Coastguard Worker    uint32_t sync_id;
1800*bbecb9d1SAndroid Build Coastguard Worker    int ret;
1801*bbecb9d1SAndroid Build Coastguard Worker 
1802*bbecb9d1SAndroid Build Coastguard Worker    ret = ctx->input->read(ctx->input, &sync_unref_buf,
1803*bbecb9d1SAndroid Build Coastguard Worker                           sizeof(sync_unref_buf));
1804*bbecb9d1SAndroid Build Coastguard Worker    if (ret != sizeof(sync_unref_buf)) {
1805*bbecb9d1SAndroid Build Coastguard Worker       return -1;
1806*bbecb9d1SAndroid Build Coastguard Worker    }
1807*bbecb9d1SAndroid Build Coastguard Worker 
1808*bbecb9d1SAndroid Build Coastguard Worker    sync_id = sync_unref_buf[VCMD_SYNC_UNREF_ID];
1809*bbecb9d1SAndroid Build Coastguard Worker    util_hash_table_remove(ctx->sync_table, intptr_to_pointer(sync_id));
1810*bbecb9d1SAndroid Build Coastguard Worker 
1811*bbecb9d1SAndroid Build Coastguard Worker    return 0;
1812*bbecb9d1SAndroid Build Coastguard Worker }
1813*bbecb9d1SAndroid Build Coastguard Worker 
vtest_sync_read(UNUSED uint32_t length_dw)1814*bbecb9d1SAndroid Build Coastguard Worker int vtest_sync_read(UNUSED uint32_t length_dw)
1815*bbecb9d1SAndroid Build Coastguard Worker {
1816*bbecb9d1SAndroid Build Coastguard Worker    struct vtest_context *ctx = vtest_get_current_context();
1817*bbecb9d1SAndroid Build Coastguard Worker    uint32_t sync_read_buf[VCMD_SYNC_READ_SIZE];
1818*bbecb9d1SAndroid Build Coastguard Worker    uint32_t resp_buf[VTEST_HDR_SIZE + 2];
1819*bbecb9d1SAndroid Build Coastguard Worker    uint32_t sync_id;
1820*bbecb9d1SAndroid Build Coastguard Worker    struct vtest_sync *sync;
1821*bbecb9d1SAndroid Build Coastguard Worker    int ret;
1822*bbecb9d1SAndroid Build Coastguard Worker 
1823*bbecb9d1SAndroid Build Coastguard Worker    ret = ctx->input->read(ctx->input, &sync_read_buf,
1824*bbecb9d1SAndroid Build Coastguard Worker                           sizeof(sync_read_buf));
1825*bbecb9d1SAndroid Build Coastguard Worker    if (ret != sizeof(sync_read_buf)) {
1826*bbecb9d1SAndroid Build Coastguard Worker       return -1;
1827*bbecb9d1SAndroid Build Coastguard Worker    }
1828*bbecb9d1SAndroid Build Coastguard Worker 
1829*bbecb9d1SAndroid Build Coastguard Worker    sync_id = sync_read_buf[VCMD_SYNC_READ_ID];
1830*bbecb9d1SAndroid Build Coastguard Worker 
1831*bbecb9d1SAndroid Build Coastguard Worker    sync = util_hash_table_get(ctx->sync_table, intptr_to_pointer(sync_id));
1832*bbecb9d1SAndroid Build Coastguard Worker    if (!sync)
1833*bbecb9d1SAndroid Build Coastguard Worker       return -EEXIST;
1834*bbecb9d1SAndroid Build Coastguard Worker 
1835*bbecb9d1SAndroid Build Coastguard Worker    resp_buf[VTEST_CMD_LEN] = 2;
1836*bbecb9d1SAndroid Build Coastguard Worker    resp_buf[VTEST_CMD_ID] = VCMD_SYNC_READ;
1837*bbecb9d1SAndroid Build Coastguard Worker    resp_buf[VTEST_CMD_DATA_START] = (uint32_t)sync->value;
1838*bbecb9d1SAndroid Build Coastguard Worker    resp_buf[VTEST_CMD_DATA_START + 1] = (uint32_t)(sync->value >> 32);
1839*bbecb9d1SAndroid Build Coastguard Worker 
1840*bbecb9d1SAndroid Build Coastguard Worker    ret = vtest_block_write(ctx->out_fd, resp_buf, sizeof(resp_buf));
1841*bbecb9d1SAndroid Build Coastguard Worker    if (ret < 0)
1842*bbecb9d1SAndroid Build Coastguard Worker       return ret;
1843*bbecb9d1SAndroid Build Coastguard Worker 
1844*bbecb9d1SAndroid Build Coastguard Worker    return 0;
1845*bbecb9d1SAndroid Build Coastguard Worker }
1846*bbecb9d1SAndroid Build Coastguard Worker 
vtest_sync_decode_id_and_value(const uint32_t * data,uint32_t index,uint64_t * value)1847*bbecb9d1SAndroid Build Coastguard Worker static uint32_t vtest_sync_decode_id_and_value(const uint32_t *data,
1848*bbecb9d1SAndroid Build Coastguard Worker                                                uint32_t index,
1849*bbecb9d1SAndroid Build Coastguard Worker                                                uint64_t *value)
1850*bbecb9d1SAndroid Build Coastguard Worker {
1851*bbecb9d1SAndroid Build Coastguard Worker    data += index * 3;
1852*bbecb9d1SAndroid Build Coastguard Worker 
1853*bbecb9d1SAndroid Build Coastguard Worker    /* 32-bit sync id followed by 64-bit sync value */
1854*bbecb9d1SAndroid Build Coastguard Worker    *value = (uint64_t)data[1];
1855*bbecb9d1SAndroid Build Coastguard Worker    *value |= (uint64_t)data[2] << 32;
1856*bbecb9d1SAndroid Build Coastguard Worker    return data[0];
1857*bbecb9d1SAndroid Build Coastguard Worker }
1858*bbecb9d1SAndroid Build Coastguard Worker 
vtest_sync_write(UNUSED uint32_t length_dw)1859*bbecb9d1SAndroid Build Coastguard Worker int vtest_sync_write(UNUSED uint32_t length_dw)
1860*bbecb9d1SAndroid Build Coastguard Worker {
1861*bbecb9d1SAndroid Build Coastguard Worker    struct vtest_context *ctx = vtest_get_current_context();
1862*bbecb9d1SAndroid Build Coastguard Worker    uint32_t sync_write_buf[VCMD_SYNC_WRITE_SIZE];
1863*bbecb9d1SAndroid Build Coastguard Worker    uint32_t sync_id;
1864*bbecb9d1SAndroid Build Coastguard Worker    uint64_t value;
1865*bbecb9d1SAndroid Build Coastguard Worker    struct vtest_sync *sync;
1866*bbecb9d1SAndroid Build Coastguard Worker    int ret;
1867*bbecb9d1SAndroid Build Coastguard Worker 
1868*bbecb9d1SAndroid Build Coastguard Worker    ret = ctx->input->read(ctx->input, &sync_write_buf,
1869*bbecb9d1SAndroid Build Coastguard Worker                           sizeof(sync_write_buf));
1870*bbecb9d1SAndroid Build Coastguard Worker    if (ret != sizeof(sync_write_buf)) {
1871*bbecb9d1SAndroid Build Coastguard Worker       return -1;
1872*bbecb9d1SAndroid Build Coastguard Worker    }
1873*bbecb9d1SAndroid Build Coastguard Worker 
1874*bbecb9d1SAndroid Build Coastguard Worker    sync_id = vtest_sync_decode_id_and_value(sync_write_buf, 0, &value);
1875*bbecb9d1SAndroid Build Coastguard Worker 
1876*bbecb9d1SAndroid Build Coastguard Worker    sync = util_hash_table_get(ctx->sync_table, intptr_to_pointer(sync_id));
1877*bbecb9d1SAndroid Build Coastguard Worker    if (!sync)
1878*bbecb9d1SAndroid Build Coastguard Worker       return -EEXIST;
1879*bbecb9d1SAndroid Build Coastguard Worker 
1880*bbecb9d1SAndroid Build Coastguard Worker    vtest_signal_sync(sync, value);
1881*bbecb9d1SAndroid Build Coastguard Worker 
1882*bbecb9d1SAndroid Build Coastguard Worker    return 0;
1883*bbecb9d1SAndroid Build Coastguard Worker }
1884*bbecb9d1SAndroid Build Coastguard Worker 
vtest_sync_wait_init(struct vtest_sync_wait * wait,struct vtest_context * ctx,uint32_t flags,uint32_t timeout,const uint32_t * syncs,uint32_t sync_count)1885*bbecb9d1SAndroid Build Coastguard Worker static int vtest_sync_wait_init(struct vtest_sync_wait *wait,
1886*bbecb9d1SAndroid Build Coastguard Worker                                 struct vtest_context *ctx,
1887*bbecb9d1SAndroid Build Coastguard Worker                                 uint32_t flags,
1888*bbecb9d1SAndroid Build Coastguard Worker                                 uint32_t timeout,
1889*bbecb9d1SAndroid Build Coastguard Worker                                 const uint32_t *syncs,
1890*bbecb9d1SAndroid Build Coastguard Worker                                 uint32_t sync_count)
1891*bbecb9d1SAndroid Build Coastguard Worker {
1892*bbecb9d1SAndroid Build Coastguard Worker    uint32_t i;
1893*bbecb9d1SAndroid Build Coastguard Worker 
1894*bbecb9d1SAndroid Build Coastguard Worker #ifdef HAVE_EVENTFD_H
1895*bbecb9d1SAndroid Build Coastguard Worker    wait->fd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);
1896*bbecb9d1SAndroid Build Coastguard Worker #else
1897*bbecb9d1SAndroid Build Coastguard Worker    /* TODO pipe */
1898*bbecb9d1SAndroid Build Coastguard Worker    wait->fd = -1;
1899*bbecb9d1SAndroid Build Coastguard Worker #endif
1900*bbecb9d1SAndroid Build Coastguard Worker    if (wait->fd < 0)
1901*bbecb9d1SAndroid Build Coastguard Worker       return -ENODEV;
1902*bbecb9d1SAndroid Build Coastguard Worker 
1903*bbecb9d1SAndroid Build Coastguard Worker    wait->flags = flags;
1904*bbecb9d1SAndroid Build Coastguard Worker    wait->valid_before = vtest_gettime(timeout);
1905*bbecb9d1SAndroid Build Coastguard Worker 
1906*bbecb9d1SAndroid Build Coastguard Worker    wait->count = 0;
1907*bbecb9d1SAndroid Build Coastguard Worker    wait->signaled_count = 0;
1908*bbecb9d1SAndroid Build Coastguard Worker    for (i = 0; i < sync_count; i++) {
1909*bbecb9d1SAndroid Build Coastguard Worker       struct vtest_sync *sync;
1910*bbecb9d1SAndroid Build Coastguard Worker       uint32_t sync_id;
1911*bbecb9d1SAndroid Build Coastguard Worker       uint64_t value;
1912*bbecb9d1SAndroid Build Coastguard Worker 
1913*bbecb9d1SAndroid Build Coastguard Worker       sync_id = vtest_sync_decode_id_and_value(syncs, i, &value);
1914*bbecb9d1SAndroid Build Coastguard Worker 
1915*bbecb9d1SAndroid Build Coastguard Worker       sync = util_hash_table_get(ctx->sync_table, intptr_to_pointer(sync_id));
1916*bbecb9d1SAndroid Build Coastguard Worker       if (!sync)
1917*bbecb9d1SAndroid Build Coastguard Worker          break;
1918*bbecb9d1SAndroid Build Coastguard Worker 
1919*bbecb9d1SAndroid Build Coastguard Worker       /* skip signaled */
1920*bbecb9d1SAndroid Build Coastguard Worker       if (sync->value < value) {
1921*bbecb9d1SAndroid Build Coastguard Worker          wait->syncs[wait->count] = vtest_ref_sync(sync);
1922*bbecb9d1SAndroid Build Coastguard Worker          wait->values[wait->count] = value;
1923*bbecb9d1SAndroid Build Coastguard Worker          wait->count++;
1924*bbecb9d1SAndroid Build Coastguard Worker       }
1925*bbecb9d1SAndroid Build Coastguard Worker    }
1926*bbecb9d1SAndroid Build Coastguard Worker 
1927*bbecb9d1SAndroid Build Coastguard Worker    if (i < sync_count) {
1928*bbecb9d1SAndroid Build Coastguard Worker       vtest_free_sync_wait(wait);
1929*bbecb9d1SAndroid Build Coastguard Worker       return -EEXIST;
1930*bbecb9d1SAndroid Build Coastguard Worker    }
1931*bbecb9d1SAndroid Build Coastguard Worker 
1932*bbecb9d1SAndroid Build Coastguard Worker    return 0;
1933*bbecb9d1SAndroid Build Coastguard Worker }
1934*bbecb9d1SAndroid Build Coastguard Worker 
vtest_sync_wait(uint32_t length_dw)1935*bbecb9d1SAndroid Build Coastguard Worker int vtest_sync_wait(uint32_t length_dw)
1936*bbecb9d1SAndroid Build Coastguard Worker {
1937*bbecb9d1SAndroid Build Coastguard Worker    struct vtest_context *ctx = vtest_get_current_context();
1938*bbecb9d1SAndroid Build Coastguard Worker    uint32_t resp_buf[VTEST_HDR_SIZE];
1939*bbecb9d1SAndroid Build Coastguard Worker    uint32_t sync_count;
1940*bbecb9d1SAndroid Build Coastguard Worker    uint32_t *sync_wait_buf;
1941*bbecb9d1SAndroid Build Coastguard Worker    uint32_t flags;
1942*bbecb9d1SAndroid Build Coastguard Worker    uint32_t timeout;
1943*bbecb9d1SAndroid Build Coastguard Worker    struct vtest_sync_wait *wait;
1944*bbecb9d1SAndroid Build Coastguard Worker    bool is_ready;
1945*bbecb9d1SAndroid Build Coastguard Worker    int ret;
1946*bbecb9d1SAndroid Build Coastguard Worker 
1947*bbecb9d1SAndroid Build Coastguard Worker    if (length_dw > renderer.max_length / 4)
1948*bbecb9d1SAndroid Build Coastguard Worker       return -EINVAL;
1949*bbecb9d1SAndroid Build Coastguard Worker 
1950*bbecb9d1SAndroid Build Coastguard Worker    if ((length_dw - 2) % 3)
1951*bbecb9d1SAndroid Build Coastguard Worker       return -EINVAL;
1952*bbecb9d1SAndroid Build Coastguard Worker    sync_count = (length_dw - 2) / 3;
1953*bbecb9d1SAndroid Build Coastguard Worker 
1954*bbecb9d1SAndroid Build Coastguard Worker    sync_wait_buf = malloc(length_dw * 4);
1955*bbecb9d1SAndroid Build Coastguard Worker    if (!sync_wait_buf)
1956*bbecb9d1SAndroid Build Coastguard Worker       return -ENOMEM;
1957*bbecb9d1SAndroid Build Coastguard Worker 
1958*bbecb9d1SAndroid Build Coastguard Worker    ret = ctx->input->read(ctx->input, sync_wait_buf, length_dw * 4);
1959*bbecb9d1SAndroid Build Coastguard Worker    if (ret != (int)length_dw * 4) {
1960*bbecb9d1SAndroid Build Coastguard Worker       free(sync_wait_buf);
1961*bbecb9d1SAndroid Build Coastguard Worker       return -1;
1962*bbecb9d1SAndroid Build Coastguard Worker    }
1963*bbecb9d1SAndroid Build Coastguard Worker 
1964*bbecb9d1SAndroid Build Coastguard Worker    flags = sync_wait_buf[VCMD_SYNC_WAIT_FLAGS];
1965*bbecb9d1SAndroid Build Coastguard Worker    timeout = sync_wait_buf[VCMD_SYNC_WAIT_TIMEOUT];
1966*bbecb9d1SAndroid Build Coastguard Worker 
1967*bbecb9d1SAndroid Build Coastguard Worker    wait = malloc(sizeof(*wait) +
1968*bbecb9d1SAndroid Build Coastguard Worker                  sizeof(*wait->syncs) * sync_count +
1969*bbecb9d1SAndroid Build Coastguard Worker                  sizeof(*wait->values) * sync_count);
1970*bbecb9d1SAndroid Build Coastguard Worker    if (!wait) {
1971*bbecb9d1SAndroid Build Coastguard Worker       free(sync_wait_buf);
1972*bbecb9d1SAndroid Build Coastguard Worker       return -ENOMEM;
1973*bbecb9d1SAndroid Build Coastguard Worker    }
1974*bbecb9d1SAndroid Build Coastguard Worker    wait->syncs = (void *)&wait[1];
1975*bbecb9d1SAndroid Build Coastguard Worker    wait->values = (void *)&wait->syncs[sync_count];
1976*bbecb9d1SAndroid Build Coastguard Worker 
1977*bbecb9d1SAndroid Build Coastguard Worker    ret = vtest_sync_wait_init(wait, ctx, flags, timeout,
1978*bbecb9d1SAndroid Build Coastguard Worker          sync_wait_buf + 2, sync_count);
1979*bbecb9d1SAndroid Build Coastguard Worker    free(sync_wait_buf);
1980*bbecb9d1SAndroid Build Coastguard Worker 
1981*bbecb9d1SAndroid Build Coastguard Worker    if (ret)
1982*bbecb9d1SAndroid Build Coastguard Worker       return ret;
1983*bbecb9d1SAndroid Build Coastguard Worker 
1984*bbecb9d1SAndroid Build Coastguard Worker    is_ready = !wait->count;
1985*bbecb9d1SAndroid Build Coastguard Worker    if ((wait->flags & VCMD_SYNC_WAIT_FLAG_ANY) && wait->count < sync_count)
1986*bbecb9d1SAndroid Build Coastguard Worker       is_ready = true;
1987*bbecb9d1SAndroid Build Coastguard Worker 
1988*bbecb9d1SAndroid Build Coastguard Worker    if (is_ready) {
1989*bbecb9d1SAndroid Build Coastguard Worker       write_ready(wait->fd);
1990*bbecb9d1SAndroid Build Coastguard Worker    }
1991*bbecb9d1SAndroid Build Coastguard Worker 
1992*bbecb9d1SAndroid Build Coastguard Worker    resp_buf[VTEST_CMD_LEN] = 0;
1993*bbecb9d1SAndroid Build Coastguard Worker    resp_buf[VTEST_CMD_ID] = VCMD_SYNC_WAIT;
1994*bbecb9d1SAndroid Build Coastguard Worker    ret = vtest_block_write(ctx->out_fd, resp_buf, sizeof(resp_buf));
1995*bbecb9d1SAndroid Build Coastguard Worker    if (ret >= 0)
1996*bbecb9d1SAndroid Build Coastguard Worker       ret = vtest_send_fd(ctx->out_fd, wait->fd);
1997*bbecb9d1SAndroid Build Coastguard Worker 
1998*bbecb9d1SAndroid Build Coastguard Worker    if (ret || is_ready || !timeout)
1999*bbecb9d1SAndroid Build Coastguard Worker       vtest_free_sync_wait(wait);
2000*bbecb9d1SAndroid Build Coastguard Worker    else
2001*bbecb9d1SAndroid Build Coastguard Worker       list_addtail(&wait->head, &ctx->sync_waits);
2002*bbecb9d1SAndroid Build Coastguard Worker 
2003*bbecb9d1SAndroid Build Coastguard Worker    return ret;
2004*bbecb9d1SAndroid Build Coastguard Worker }
2005*bbecb9d1SAndroid Build Coastguard Worker 
vtest_submit_cmd2_batch(struct vtest_context * ctx,const struct vcmd_submit_cmd2_batch * batch,const uint32_t * cmds,const uint32_t * syncs)2006*bbecb9d1SAndroid Build Coastguard Worker static int vtest_submit_cmd2_batch(struct vtest_context *ctx,
2007*bbecb9d1SAndroid Build Coastguard Worker                                    const struct vcmd_submit_cmd2_batch *batch,
2008*bbecb9d1SAndroid Build Coastguard Worker                                    const uint32_t *cmds,
2009*bbecb9d1SAndroid Build Coastguard Worker                                    const uint32_t *syncs)
2010*bbecb9d1SAndroid Build Coastguard Worker {
2011*bbecb9d1SAndroid Build Coastguard Worker    struct vtest_timeline_submit *submit = NULL;
2012*bbecb9d1SAndroid Build Coastguard Worker    uint32_t i;
2013*bbecb9d1SAndroid Build Coastguard Worker    int ret;
2014*bbecb9d1SAndroid Build Coastguard Worker 
2015*bbecb9d1SAndroid Build Coastguard Worker    ret = virgl_renderer_submit_cmd((void *)cmds, ctx->ctx_id, batch->cmd_size);
2016*bbecb9d1SAndroid Build Coastguard Worker    if (ret)
2017*bbecb9d1SAndroid Build Coastguard Worker       return -EINVAL;
2018*bbecb9d1SAndroid Build Coastguard Worker 
2019*bbecb9d1SAndroid Build Coastguard Worker    if (!batch->sync_count)
2020*bbecb9d1SAndroid Build Coastguard Worker       return 0;
2021*bbecb9d1SAndroid Build Coastguard Worker 
2022*bbecb9d1SAndroid Build Coastguard Worker    if (batch->flags & VCMD_SUBMIT_CMD2_FLAG_RING_IDX) {
2023*bbecb9d1SAndroid Build Coastguard Worker       submit = malloc(sizeof(*submit) +
2024*bbecb9d1SAndroid Build Coastguard Worker                       sizeof(*submit->syncs) * batch->sync_count +
2025*bbecb9d1SAndroid Build Coastguard Worker                       sizeof(*submit->values) * batch->sync_count);
2026*bbecb9d1SAndroid Build Coastguard Worker       if (!submit)
2027*bbecb9d1SAndroid Build Coastguard Worker          return -ENOMEM;
2028*bbecb9d1SAndroid Build Coastguard Worker 
2029*bbecb9d1SAndroid Build Coastguard Worker       submit->count = batch->sync_count;
2030*bbecb9d1SAndroid Build Coastguard Worker       submit->syncs = (void *)&submit[1];
2031*bbecb9d1SAndroid Build Coastguard Worker       submit->values = (void *)&submit->syncs[batch->sync_count];
2032*bbecb9d1SAndroid Build Coastguard Worker    }
2033*bbecb9d1SAndroid Build Coastguard Worker 
2034*bbecb9d1SAndroid Build Coastguard Worker    for (i = 0; i < batch->sync_count; i++) {
2035*bbecb9d1SAndroid Build Coastguard Worker       struct vtest_sync *sync;
2036*bbecb9d1SAndroid Build Coastguard Worker       uint32_t sync_id;
2037*bbecb9d1SAndroid Build Coastguard Worker       uint64_t value;
2038*bbecb9d1SAndroid Build Coastguard Worker 
2039*bbecb9d1SAndroid Build Coastguard Worker       sync_id = vtest_sync_decode_id_and_value(syncs, i, &value);
2040*bbecb9d1SAndroid Build Coastguard Worker 
2041*bbecb9d1SAndroid Build Coastguard Worker       sync = util_hash_table_get(ctx->sync_table, intptr_to_pointer(sync_id));
2042*bbecb9d1SAndroid Build Coastguard Worker       if (!sync)
2043*bbecb9d1SAndroid Build Coastguard Worker          break;
2044*bbecb9d1SAndroid Build Coastguard Worker 
2045*bbecb9d1SAndroid Build Coastguard Worker       if (submit) {
2046*bbecb9d1SAndroid Build Coastguard Worker          submit->syncs[i] = vtest_ref_sync(sync);
2047*bbecb9d1SAndroid Build Coastguard Worker          submit->values[i] = value;
2048*bbecb9d1SAndroid Build Coastguard Worker       } else {
2049*bbecb9d1SAndroid Build Coastguard Worker          vtest_signal_sync(sync, value);
2050*bbecb9d1SAndroid Build Coastguard Worker       }
2051*bbecb9d1SAndroid Build Coastguard Worker    }
2052*bbecb9d1SAndroid Build Coastguard Worker 
2053*bbecb9d1SAndroid Build Coastguard Worker    if (i < batch->sync_count) {
2054*bbecb9d1SAndroid Build Coastguard Worker       if (submit) {
2055*bbecb9d1SAndroid Build Coastguard Worker          submit->count = i;
2056*bbecb9d1SAndroid Build Coastguard Worker          vtest_free_timeline_submit(submit);
2057*bbecb9d1SAndroid Build Coastguard Worker       }
2058*bbecb9d1SAndroid Build Coastguard Worker       return -EEXIST;
2059*bbecb9d1SAndroid Build Coastguard Worker    }
2060*bbecb9d1SAndroid Build Coastguard Worker 
2061*bbecb9d1SAndroid Build Coastguard Worker    if (submit) {
2062*bbecb9d1SAndroid Build Coastguard Worker       struct vtest_timeline *timeline = &ctx->timelines[batch->ring_idx];
2063*bbecb9d1SAndroid Build Coastguard Worker 
2064*bbecb9d1SAndroid Build Coastguard Worker       submit->timeline = timeline;
2065*bbecb9d1SAndroid Build Coastguard Worker       ret = virgl_renderer_context_create_fence(ctx->ctx_id,
2066*bbecb9d1SAndroid Build Coastguard Worker                                                 VIRGL_RENDERER_FENCE_FLAG_MERGEABLE,
2067*bbecb9d1SAndroid Build Coastguard Worker                                                 batch->ring_idx,
2068*bbecb9d1SAndroid Build Coastguard Worker                                                 (uintptr_t)submit);
2069*bbecb9d1SAndroid Build Coastguard Worker       if (ret) {
2070*bbecb9d1SAndroid Build Coastguard Worker          vtest_free_timeline_submit(submit);
2071*bbecb9d1SAndroid Build Coastguard Worker          return ret;
2072*bbecb9d1SAndroid Build Coastguard Worker       }
2073*bbecb9d1SAndroid Build Coastguard Worker 
2074*bbecb9d1SAndroid Build Coastguard Worker       list_addtail(&submit->head, &timeline->submits);
2075*bbecb9d1SAndroid Build Coastguard Worker    }
2076*bbecb9d1SAndroid Build Coastguard Worker 
2077*bbecb9d1SAndroid Build Coastguard Worker    return 0;
2078*bbecb9d1SAndroid Build Coastguard Worker }
2079*bbecb9d1SAndroid Build Coastguard Worker 
vtest_submit_cmd2(uint32_t length_dw)2080*bbecb9d1SAndroid Build Coastguard Worker int vtest_submit_cmd2(uint32_t length_dw)
2081*bbecb9d1SAndroid Build Coastguard Worker {
2082*bbecb9d1SAndroid Build Coastguard Worker    struct vtest_context *ctx = vtest_get_current_context();
2083*bbecb9d1SAndroid Build Coastguard Worker    uint32_t *submit_cmd2_buf;
2084*bbecb9d1SAndroid Build Coastguard Worker    uint32_t batch_count;
2085*bbecb9d1SAndroid Build Coastguard Worker    uint32_t i;
2086*bbecb9d1SAndroid Build Coastguard Worker    int ret;
2087*bbecb9d1SAndroid Build Coastguard Worker 
2088*bbecb9d1SAndroid Build Coastguard Worker    if (length_dw > renderer.max_length / 4)
2089*bbecb9d1SAndroid Build Coastguard Worker       return -EINVAL;
2090*bbecb9d1SAndroid Build Coastguard Worker 
2091*bbecb9d1SAndroid Build Coastguard Worker    submit_cmd2_buf = malloc(length_dw * 4);
2092*bbecb9d1SAndroid Build Coastguard Worker    if (!submit_cmd2_buf)
2093*bbecb9d1SAndroid Build Coastguard Worker       return -ENOMEM;
2094*bbecb9d1SAndroid Build Coastguard Worker 
2095*bbecb9d1SAndroid Build Coastguard Worker    ret = ctx->input->read(ctx->input, submit_cmd2_buf, length_dw * 4);
2096*bbecb9d1SAndroid Build Coastguard Worker    if (ret != (int)length_dw * 4) {
2097*bbecb9d1SAndroid Build Coastguard Worker       free(submit_cmd2_buf);
2098*bbecb9d1SAndroid Build Coastguard Worker       return -1;
2099*bbecb9d1SAndroid Build Coastguard Worker    }
2100*bbecb9d1SAndroid Build Coastguard Worker 
2101*bbecb9d1SAndroid Build Coastguard Worker    batch_count = submit_cmd2_buf[VCMD_SUBMIT_CMD2_BATCH_COUNT];
2102*bbecb9d1SAndroid Build Coastguard Worker    if (VCMD_SUBMIT_CMD2_BATCH_COUNT + 6 * batch_count > length_dw) {
2103*bbecb9d1SAndroid Build Coastguard Worker       free(submit_cmd2_buf);
2104*bbecb9d1SAndroid Build Coastguard Worker       return -EINVAL;
2105*bbecb9d1SAndroid Build Coastguard Worker    }
2106*bbecb9d1SAndroid Build Coastguard Worker 
2107*bbecb9d1SAndroid Build Coastguard Worker    for (i = 0; i < batch_count; i++) {
2108*bbecb9d1SAndroid Build Coastguard Worker       const struct vcmd_submit_cmd2_batch batch = {
2109*bbecb9d1SAndroid Build Coastguard Worker          .flags = submit_cmd2_buf[VCMD_SUBMIT_CMD2_BATCH_FLAGS(i)],
2110*bbecb9d1SAndroid Build Coastguard Worker          .cmd_offset = submit_cmd2_buf[VCMD_SUBMIT_CMD2_BATCH_CMD_OFFSET(i)],
2111*bbecb9d1SAndroid Build Coastguard Worker          .cmd_size = submit_cmd2_buf[VCMD_SUBMIT_CMD2_BATCH_CMD_SIZE(i)],
2112*bbecb9d1SAndroid Build Coastguard Worker          .sync_offset = submit_cmd2_buf[VCMD_SUBMIT_CMD2_BATCH_SYNC_OFFSET(i)],
2113*bbecb9d1SAndroid Build Coastguard Worker          .sync_count = submit_cmd2_buf[VCMD_SUBMIT_CMD2_BATCH_SYNC_COUNT(i)],
2114*bbecb9d1SAndroid Build Coastguard Worker          .ring_idx = submit_cmd2_buf[VCMD_SUBMIT_CMD2_BATCH_RING_IDX(i)],
2115*bbecb9d1SAndroid Build Coastguard Worker       };
2116*bbecb9d1SAndroid Build Coastguard Worker       const uint32_t *cmds = &submit_cmd2_buf[batch.cmd_offset];
2117*bbecb9d1SAndroid Build Coastguard Worker       const uint32_t *syncs = &submit_cmd2_buf[batch.sync_offset];
2118*bbecb9d1SAndroid Build Coastguard Worker 
2119*bbecb9d1SAndroid Build Coastguard Worker       if (batch.cmd_offset + batch.cmd_size > length_dw ||
2120*bbecb9d1SAndroid Build Coastguard Worker           batch.sync_offset + batch.sync_count * 3 > length_dw ||
2121*bbecb9d1SAndroid Build Coastguard Worker           batch.ring_idx >= VTEST_MAX_TIMELINE_COUNT) {
2122*bbecb9d1SAndroid Build Coastguard Worker          free(submit_cmd2_buf);
2123*bbecb9d1SAndroid Build Coastguard Worker          return -EINVAL;
2124*bbecb9d1SAndroid Build Coastguard Worker       }
2125*bbecb9d1SAndroid Build Coastguard Worker 
2126*bbecb9d1SAndroid Build Coastguard Worker       ret = vtest_submit_cmd2_batch(ctx, &batch, cmds, syncs);
2127*bbecb9d1SAndroid Build Coastguard Worker       if (ret) {
2128*bbecb9d1SAndroid Build Coastguard Worker          free(submit_cmd2_buf);
2129*bbecb9d1SAndroid Build Coastguard Worker          return ret;
2130*bbecb9d1SAndroid Build Coastguard Worker       }
2131*bbecb9d1SAndroid Build Coastguard Worker    }
2132*bbecb9d1SAndroid Build Coastguard Worker 
2133*bbecb9d1SAndroid Build Coastguard Worker    free(submit_cmd2_buf);
2134*bbecb9d1SAndroid Build Coastguard Worker 
2135*bbecb9d1SAndroid Build Coastguard Worker    return 0;
2136*bbecb9d1SAndroid Build Coastguard Worker }
2137*bbecb9d1SAndroid Build Coastguard Worker 
vtest_set_max_length(uint32_t length)2138*bbecb9d1SAndroid Build Coastguard Worker void vtest_set_max_length(uint32_t length)
2139*bbecb9d1SAndroid Build Coastguard Worker {
2140*bbecb9d1SAndroid Build Coastguard Worker    renderer.max_length = length;
2141*bbecb9d1SAndroid Build Coastguard Worker }
2142