1*bbecb9d1SAndroid Build Coastguard Worker /*
2*bbecb9d1SAndroid Build Coastguard Worker * Copyright 2020 Google LLC
3*bbecb9d1SAndroid Build Coastguard Worker * SPDX-License-Identifier: MIT
4*bbecb9d1SAndroid Build Coastguard Worker */
5*bbecb9d1SAndroid Build Coastguard Worker
6*bbecb9d1SAndroid Build Coastguard Worker #include "vkr_context.h"
7*bbecb9d1SAndroid Build Coastguard Worker
8*bbecb9d1SAndroid Build Coastguard Worker #include <sys/mman.h>
9*bbecb9d1SAndroid Build Coastguard Worker #include <sys/types.h>
10*bbecb9d1SAndroid Build Coastguard Worker #include <unistd.h>
11*bbecb9d1SAndroid Build Coastguard Worker
12*bbecb9d1SAndroid Build Coastguard Worker #include "pipe/p_state.h"
13*bbecb9d1SAndroid Build Coastguard Worker #include "util/anon_file.h"
14*bbecb9d1SAndroid Build Coastguard Worker #include "venus-protocol/vn_protocol_renderer_dispatches.h"
15*bbecb9d1SAndroid Build Coastguard Worker
16*bbecb9d1SAndroid Build Coastguard Worker #define XXH_INLINE_ALL
17*bbecb9d1SAndroid Build Coastguard Worker #include "util/xxhash.h"
18*bbecb9d1SAndroid Build Coastguard Worker
19*bbecb9d1SAndroid Build Coastguard Worker #include "vkr_buffer.h"
20*bbecb9d1SAndroid Build Coastguard Worker #include "vkr_command_buffer.h"
21*bbecb9d1SAndroid Build Coastguard Worker #include "vkr_context.h"
22*bbecb9d1SAndroid Build Coastguard Worker #include "vkr_cs.h"
23*bbecb9d1SAndroid Build Coastguard Worker #include "vkr_descriptor_set.h"
24*bbecb9d1SAndroid Build Coastguard Worker #include "vkr_device.h"
25*bbecb9d1SAndroid Build Coastguard Worker #include "vkr_device_memory.h"
26*bbecb9d1SAndroid Build Coastguard Worker #include "vkr_image.h"
27*bbecb9d1SAndroid Build Coastguard Worker #include "vkr_instance.h"
28*bbecb9d1SAndroid Build Coastguard Worker #include "vkr_physical_device.h"
29*bbecb9d1SAndroid Build Coastguard Worker #include "vkr_pipeline.h"
30*bbecb9d1SAndroid Build Coastguard Worker #include "vkr_query_pool.h"
31*bbecb9d1SAndroid Build Coastguard Worker #include "vkr_queue.h"
32*bbecb9d1SAndroid Build Coastguard Worker #include "vkr_render_pass.h"
33*bbecb9d1SAndroid Build Coastguard Worker #include "vkr_ring.h"
34*bbecb9d1SAndroid Build Coastguard Worker #include "vkr_transport.h"
35*bbecb9d1SAndroid Build Coastguard Worker
36*bbecb9d1SAndroid Build Coastguard Worker void
vkr_context_add_instance(struct vkr_context * ctx,struct vkr_instance * instance,const char * name)37*bbecb9d1SAndroid Build Coastguard Worker vkr_context_add_instance(struct vkr_context *ctx,
38*bbecb9d1SAndroid Build Coastguard Worker struct vkr_instance *instance,
39*bbecb9d1SAndroid Build Coastguard Worker const char *name)
40*bbecb9d1SAndroid Build Coastguard Worker {
41*bbecb9d1SAndroid Build Coastguard Worker vkr_context_add_object(ctx, &instance->base);
42*bbecb9d1SAndroid Build Coastguard Worker
43*bbecb9d1SAndroid Build Coastguard Worker assert(!ctx->instance);
44*bbecb9d1SAndroid Build Coastguard Worker ctx->instance = instance;
45*bbecb9d1SAndroid Build Coastguard Worker
46*bbecb9d1SAndroid Build Coastguard Worker if (name && name[0] != '\0') {
47*bbecb9d1SAndroid Build Coastguard Worker assert(!ctx->instance_name);
48*bbecb9d1SAndroid Build Coastguard Worker ctx->instance_name = strdup(name);
49*bbecb9d1SAndroid Build Coastguard Worker }
50*bbecb9d1SAndroid Build Coastguard Worker }
51*bbecb9d1SAndroid Build Coastguard Worker
52*bbecb9d1SAndroid Build Coastguard Worker void
vkr_context_remove_instance(struct vkr_context * ctx,struct vkr_instance * instance)53*bbecb9d1SAndroid Build Coastguard Worker vkr_context_remove_instance(struct vkr_context *ctx, struct vkr_instance *instance)
54*bbecb9d1SAndroid Build Coastguard Worker {
55*bbecb9d1SAndroid Build Coastguard Worker assert(ctx->instance && ctx->instance == instance);
56*bbecb9d1SAndroid Build Coastguard Worker ctx->instance = NULL;
57*bbecb9d1SAndroid Build Coastguard Worker
58*bbecb9d1SAndroid Build Coastguard Worker if (ctx->instance_name) {
59*bbecb9d1SAndroid Build Coastguard Worker free(ctx->instance_name);
60*bbecb9d1SAndroid Build Coastguard Worker ctx->instance_name = NULL;
61*bbecb9d1SAndroid Build Coastguard Worker }
62*bbecb9d1SAndroid Build Coastguard Worker
63*bbecb9d1SAndroid Build Coastguard Worker vkr_context_remove_object(ctx, &instance->base);
64*bbecb9d1SAndroid Build Coastguard Worker }
65*bbecb9d1SAndroid Build Coastguard Worker
66*bbecb9d1SAndroid Build Coastguard Worker static void
vkr_dispatch_debug_log(UNUSED struct vn_dispatch_context * dispatch,const char * msg)67*bbecb9d1SAndroid Build Coastguard Worker vkr_dispatch_debug_log(UNUSED struct vn_dispatch_context *dispatch, const char *msg)
68*bbecb9d1SAndroid Build Coastguard Worker {
69*bbecb9d1SAndroid Build Coastguard Worker vkr_log(msg);
70*bbecb9d1SAndroid Build Coastguard Worker }
71*bbecb9d1SAndroid Build Coastguard Worker
72*bbecb9d1SAndroid Build Coastguard Worker static void
vkr_context_init_dispatch(struct vkr_context * ctx)73*bbecb9d1SAndroid Build Coastguard Worker vkr_context_init_dispatch(struct vkr_context *ctx)
74*bbecb9d1SAndroid Build Coastguard Worker {
75*bbecb9d1SAndroid Build Coastguard Worker struct vn_dispatch_context *dispatch = &ctx->dispatch;
76*bbecb9d1SAndroid Build Coastguard Worker
77*bbecb9d1SAndroid Build Coastguard Worker dispatch->data = ctx;
78*bbecb9d1SAndroid Build Coastguard Worker dispatch->debug_log = vkr_dispatch_debug_log;
79*bbecb9d1SAndroid Build Coastguard Worker
80*bbecb9d1SAndroid Build Coastguard Worker dispatch->encoder = (struct vn_cs_encoder *)&ctx->encoder;
81*bbecb9d1SAndroid Build Coastguard Worker dispatch->decoder = (struct vn_cs_decoder *)&ctx->decoder;
82*bbecb9d1SAndroid Build Coastguard Worker
83*bbecb9d1SAndroid Build Coastguard Worker vkr_context_init_transport_dispatch(ctx);
84*bbecb9d1SAndroid Build Coastguard Worker
85*bbecb9d1SAndroid Build Coastguard Worker vkr_context_init_instance_dispatch(ctx);
86*bbecb9d1SAndroid Build Coastguard Worker vkr_context_init_physical_device_dispatch(ctx);
87*bbecb9d1SAndroid Build Coastguard Worker vkr_context_init_device_dispatch(ctx);
88*bbecb9d1SAndroid Build Coastguard Worker
89*bbecb9d1SAndroid Build Coastguard Worker vkr_context_init_queue_dispatch(ctx);
90*bbecb9d1SAndroid Build Coastguard Worker vkr_context_init_fence_dispatch(ctx);
91*bbecb9d1SAndroid Build Coastguard Worker vkr_context_init_semaphore_dispatch(ctx);
92*bbecb9d1SAndroid Build Coastguard Worker vkr_context_init_event_dispatch(ctx);
93*bbecb9d1SAndroid Build Coastguard Worker
94*bbecb9d1SAndroid Build Coastguard Worker vkr_context_init_device_memory_dispatch(ctx);
95*bbecb9d1SAndroid Build Coastguard Worker
96*bbecb9d1SAndroid Build Coastguard Worker vkr_context_init_buffer_dispatch(ctx);
97*bbecb9d1SAndroid Build Coastguard Worker vkr_context_init_buffer_view_dispatch(ctx);
98*bbecb9d1SAndroid Build Coastguard Worker
99*bbecb9d1SAndroid Build Coastguard Worker vkr_context_init_image_dispatch(ctx);
100*bbecb9d1SAndroid Build Coastguard Worker vkr_context_init_image_view_dispatch(ctx);
101*bbecb9d1SAndroid Build Coastguard Worker vkr_context_init_sampler_dispatch(ctx);
102*bbecb9d1SAndroid Build Coastguard Worker vkr_context_init_sampler_ycbcr_conversion_dispatch(ctx);
103*bbecb9d1SAndroid Build Coastguard Worker
104*bbecb9d1SAndroid Build Coastguard Worker vkr_context_init_descriptor_set_layout_dispatch(ctx);
105*bbecb9d1SAndroid Build Coastguard Worker vkr_context_init_descriptor_pool_dispatch(ctx);
106*bbecb9d1SAndroid Build Coastguard Worker vkr_context_init_descriptor_set_dispatch(ctx);
107*bbecb9d1SAndroid Build Coastguard Worker vkr_context_init_descriptor_update_template_dispatch(ctx);
108*bbecb9d1SAndroid Build Coastguard Worker
109*bbecb9d1SAndroid Build Coastguard Worker vkr_context_init_render_pass_dispatch(ctx);
110*bbecb9d1SAndroid Build Coastguard Worker vkr_context_init_framebuffer_dispatch(ctx);
111*bbecb9d1SAndroid Build Coastguard Worker
112*bbecb9d1SAndroid Build Coastguard Worker vkr_context_init_query_pool_dispatch(ctx);
113*bbecb9d1SAndroid Build Coastguard Worker
114*bbecb9d1SAndroid Build Coastguard Worker vkr_context_init_shader_module_dispatch(ctx);
115*bbecb9d1SAndroid Build Coastguard Worker vkr_context_init_pipeline_layout_dispatch(ctx);
116*bbecb9d1SAndroid Build Coastguard Worker vkr_context_init_pipeline_cache_dispatch(ctx);
117*bbecb9d1SAndroid Build Coastguard Worker vkr_context_init_pipeline_dispatch(ctx);
118*bbecb9d1SAndroid Build Coastguard Worker
119*bbecb9d1SAndroid Build Coastguard Worker vkr_context_init_command_pool_dispatch(ctx);
120*bbecb9d1SAndroid Build Coastguard Worker vkr_context_init_command_buffer_dispatch(ctx);
121*bbecb9d1SAndroid Build Coastguard Worker }
122*bbecb9d1SAndroid Build Coastguard Worker
123*bbecb9d1SAndroid Build Coastguard Worker static struct vkr_cpu_sync *
vkr_alloc_cpu_sync(uint32_t flags,uint32_t ring_idx,uint64_t fence_id)124*bbecb9d1SAndroid Build Coastguard Worker vkr_alloc_cpu_sync(uint32_t flags, uint32_t ring_idx, uint64_t fence_id)
125*bbecb9d1SAndroid Build Coastguard Worker {
126*bbecb9d1SAndroid Build Coastguard Worker struct vkr_cpu_sync *sync;
127*bbecb9d1SAndroid Build Coastguard Worker sync = malloc(sizeof(*sync));
128*bbecb9d1SAndroid Build Coastguard Worker if (!sync)
129*bbecb9d1SAndroid Build Coastguard Worker return NULL;
130*bbecb9d1SAndroid Build Coastguard Worker
131*bbecb9d1SAndroid Build Coastguard Worker sync->flags = flags;
132*bbecb9d1SAndroid Build Coastguard Worker sync->fence_id = fence_id;
133*bbecb9d1SAndroid Build Coastguard Worker sync->ring_idx = ring_idx;
134*bbecb9d1SAndroid Build Coastguard Worker list_inithead(&sync->head);
135*bbecb9d1SAndroid Build Coastguard Worker
136*bbecb9d1SAndroid Build Coastguard Worker return sync;
137*bbecb9d1SAndroid Build Coastguard Worker }
138*bbecb9d1SAndroid Build Coastguard Worker
139*bbecb9d1SAndroid Build Coastguard Worker static int
vkr_context_submit_fence_locked(struct virgl_context * base,uint32_t flags,uint32_t ring_idx,uint64_t fence_id)140*bbecb9d1SAndroid Build Coastguard Worker vkr_context_submit_fence_locked(struct virgl_context *base,
141*bbecb9d1SAndroid Build Coastguard Worker uint32_t flags,
142*bbecb9d1SAndroid Build Coastguard Worker uint32_t ring_idx,
143*bbecb9d1SAndroid Build Coastguard Worker uint64_t fence_id)
144*bbecb9d1SAndroid Build Coastguard Worker {
145*bbecb9d1SAndroid Build Coastguard Worker struct vkr_context *ctx = (struct vkr_context *)base;
146*bbecb9d1SAndroid Build Coastguard Worker VkResult result;
147*bbecb9d1SAndroid Build Coastguard Worker
148*bbecb9d1SAndroid Build Coastguard Worker if (ring_idx >= ARRAY_SIZE(ctx->sync_queues)) {
149*bbecb9d1SAndroid Build Coastguard Worker vkr_log("invalid sync ring_idx %u", ring_idx);
150*bbecb9d1SAndroid Build Coastguard Worker return -EINVAL;
151*bbecb9d1SAndroid Build Coastguard Worker }
152*bbecb9d1SAndroid Build Coastguard Worker
153*bbecb9d1SAndroid Build Coastguard Worker if (ring_idx == 0) {
154*bbecb9d1SAndroid Build Coastguard Worker if (vkr_renderer_flags & VKR_RENDERER_ASYNC_FENCE_CB) {
155*bbecb9d1SAndroid Build Coastguard Worker ctx->base.fence_retire(&ctx->base, ring_idx, fence_id);
156*bbecb9d1SAndroid Build Coastguard Worker } else {
157*bbecb9d1SAndroid Build Coastguard Worker struct vkr_cpu_sync *sync = vkr_alloc_cpu_sync(flags, ring_idx, fence_id);
158*bbecb9d1SAndroid Build Coastguard Worker if (!sync)
159*bbecb9d1SAndroid Build Coastguard Worker return -ENOMEM;
160*bbecb9d1SAndroid Build Coastguard Worker
161*bbecb9d1SAndroid Build Coastguard Worker list_addtail(&sync->head, &ctx->signaled_cpu_syncs);
162*bbecb9d1SAndroid Build Coastguard Worker }
163*bbecb9d1SAndroid Build Coastguard Worker return 0;
164*bbecb9d1SAndroid Build Coastguard Worker } else if (!ctx->sync_queues[ring_idx]) {
165*bbecb9d1SAndroid Build Coastguard Worker vkr_log("invalid ring_idx %u", ring_idx);
166*bbecb9d1SAndroid Build Coastguard Worker return -EINVAL;
167*bbecb9d1SAndroid Build Coastguard Worker }
168*bbecb9d1SAndroid Build Coastguard Worker
169*bbecb9d1SAndroid Build Coastguard Worker struct vkr_queue *queue = ctx->sync_queues[ring_idx];
170*bbecb9d1SAndroid Build Coastguard Worker struct vkr_device *dev = queue->device;
171*bbecb9d1SAndroid Build Coastguard Worker struct vn_device_proc_table *vk = &dev->proc_table;
172*bbecb9d1SAndroid Build Coastguard Worker
173*bbecb9d1SAndroid Build Coastguard Worker struct vkr_queue_sync *sync =
174*bbecb9d1SAndroid Build Coastguard Worker vkr_device_alloc_queue_sync(dev, flags, ring_idx, fence_id);
175*bbecb9d1SAndroid Build Coastguard Worker if (!sync)
176*bbecb9d1SAndroid Build Coastguard Worker return -ENOMEM;
177*bbecb9d1SAndroid Build Coastguard Worker
178*bbecb9d1SAndroid Build Coastguard Worker result = vk->QueueSubmit(queue->base.handle.queue, 0, NULL, sync->fence);
179*bbecb9d1SAndroid Build Coastguard Worker if (result == VK_ERROR_DEVICE_LOST) {
180*bbecb9d1SAndroid Build Coastguard Worker sync->device_lost = true;
181*bbecb9d1SAndroid Build Coastguard Worker } else if (result != VK_SUCCESS) {
182*bbecb9d1SAndroid Build Coastguard Worker vkr_device_free_queue_sync(dev, sync);
183*bbecb9d1SAndroid Build Coastguard Worker return -1;
184*bbecb9d1SAndroid Build Coastguard Worker }
185*bbecb9d1SAndroid Build Coastguard Worker
186*bbecb9d1SAndroid Build Coastguard Worker if (vkr_renderer_flags & VKR_RENDERER_THREAD_SYNC) {
187*bbecb9d1SAndroid Build Coastguard Worker mtx_lock(&queue->mutex);
188*bbecb9d1SAndroid Build Coastguard Worker list_addtail(&sync->head, &queue->pending_syncs);
189*bbecb9d1SAndroid Build Coastguard Worker mtx_unlock(&queue->mutex);
190*bbecb9d1SAndroid Build Coastguard Worker cnd_signal(&queue->cond);
191*bbecb9d1SAndroid Build Coastguard Worker } else {
192*bbecb9d1SAndroid Build Coastguard Worker list_addtail(&sync->head, &queue->pending_syncs);
193*bbecb9d1SAndroid Build Coastguard Worker }
194*bbecb9d1SAndroid Build Coastguard Worker
195*bbecb9d1SAndroid Build Coastguard Worker if (LIST_IS_EMPTY(&queue->busy_head))
196*bbecb9d1SAndroid Build Coastguard Worker list_addtail(&queue->busy_head, &ctx->busy_queues);
197*bbecb9d1SAndroid Build Coastguard Worker
198*bbecb9d1SAndroid Build Coastguard Worker return 0;
199*bbecb9d1SAndroid Build Coastguard Worker }
200*bbecb9d1SAndroid Build Coastguard Worker
201*bbecb9d1SAndroid Build Coastguard Worker static int
vkr_context_submit_fence(struct virgl_context * base,uint32_t flags,uint32_t ring_idx,uint64_t fence_id)202*bbecb9d1SAndroid Build Coastguard Worker vkr_context_submit_fence(struct virgl_context *base,
203*bbecb9d1SAndroid Build Coastguard Worker uint32_t flags,
204*bbecb9d1SAndroid Build Coastguard Worker uint32_t ring_idx,
205*bbecb9d1SAndroid Build Coastguard Worker uint64_t fence_id)
206*bbecb9d1SAndroid Build Coastguard Worker {
207*bbecb9d1SAndroid Build Coastguard Worker struct vkr_context *ctx = (struct vkr_context *)base;
208*bbecb9d1SAndroid Build Coastguard Worker int ret;
209*bbecb9d1SAndroid Build Coastguard Worker
210*bbecb9d1SAndroid Build Coastguard Worker /* always merge fences */
211*bbecb9d1SAndroid Build Coastguard Worker assert(!(flags & ~VIRGL_RENDERER_FENCE_FLAG_MERGEABLE));
212*bbecb9d1SAndroid Build Coastguard Worker flags = VIRGL_RENDERER_FENCE_FLAG_MERGEABLE;
213*bbecb9d1SAndroid Build Coastguard Worker
214*bbecb9d1SAndroid Build Coastguard Worker mtx_lock(&ctx->mutex);
215*bbecb9d1SAndroid Build Coastguard Worker ret = vkr_context_submit_fence_locked(base, flags, ring_idx, fence_id);
216*bbecb9d1SAndroid Build Coastguard Worker mtx_unlock(&ctx->mutex);
217*bbecb9d1SAndroid Build Coastguard Worker return ret;
218*bbecb9d1SAndroid Build Coastguard Worker }
219*bbecb9d1SAndroid Build Coastguard Worker
220*bbecb9d1SAndroid Build Coastguard Worker static void
vkr_context_retire_fences_locked(struct virgl_context * base)221*bbecb9d1SAndroid Build Coastguard Worker vkr_context_retire_fences_locked(struct virgl_context *base)
222*bbecb9d1SAndroid Build Coastguard Worker {
223*bbecb9d1SAndroid Build Coastguard Worker struct vkr_context *ctx = (struct vkr_context *)base;
224*bbecb9d1SAndroid Build Coastguard Worker struct vkr_queue_sync *sync, *sync_tmp;
225*bbecb9d1SAndroid Build Coastguard Worker struct vkr_queue *queue, *queue_tmp;
226*bbecb9d1SAndroid Build Coastguard Worker
227*bbecb9d1SAndroid Build Coastguard Worker assert(!(vkr_renderer_flags & VKR_RENDERER_ASYNC_FENCE_CB));
228*bbecb9d1SAndroid Build Coastguard Worker
229*bbecb9d1SAndroid Build Coastguard Worker /* retire syncs from destroyed devices */
230*bbecb9d1SAndroid Build Coastguard Worker LIST_FOR_EACH_ENTRY_SAFE (sync, sync_tmp, &ctx->signaled_syncs, head) {
231*bbecb9d1SAndroid Build Coastguard Worker /* ring_idx might have already get reused but is opaque to the clients */
232*bbecb9d1SAndroid Build Coastguard Worker ctx->base.fence_retire(&ctx->base, sync->ring_idx, sync->fence_id);
233*bbecb9d1SAndroid Build Coastguard Worker free(sync);
234*bbecb9d1SAndroid Build Coastguard Worker }
235*bbecb9d1SAndroid Build Coastguard Worker list_inithead(&ctx->signaled_syncs);
236*bbecb9d1SAndroid Build Coastguard Worker
237*bbecb9d1SAndroid Build Coastguard Worker /* retire syncs from CPU timeline */
238*bbecb9d1SAndroid Build Coastguard Worker struct vkr_cpu_sync *cpu_sync, *cpu_sync_tmp;
239*bbecb9d1SAndroid Build Coastguard Worker LIST_FOR_EACH_ENTRY_SAFE (cpu_sync, cpu_sync_tmp, &ctx->signaled_cpu_syncs, head) {
240*bbecb9d1SAndroid Build Coastguard Worker ctx->base.fence_retire(&ctx->base, cpu_sync->ring_idx, cpu_sync->fence_id);
241*bbecb9d1SAndroid Build Coastguard Worker free(cpu_sync);
242*bbecb9d1SAndroid Build Coastguard Worker }
243*bbecb9d1SAndroid Build Coastguard Worker list_inithead(&ctx->signaled_cpu_syncs);
244*bbecb9d1SAndroid Build Coastguard Worker
245*bbecb9d1SAndroid Build Coastguard Worker /* flush first and once because the per-queue sync threads might write to
246*bbecb9d1SAndroid Build Coastguard Worker * it any time
247*bbecb9d1SAndroid Build Coastguard Worker */
248*bbecb9d1SAndroid Build Coastguard Worker if (ctx->fence_eventfd >= 0)
249*bbecb9d1SAndroid Build Coastguard Worker flush_eventfd(ctx->fence_eventfd);
250*bbecb9d1SAndroid Build Coastguard Worker
251*bbecb9d1SAndroid Build Coastguard Worker LIST_FOR_EACH_ENTRY_SAFE (queue, queue_tmp, &ctx->busy_queues, busy_head) {
252*bbecb9d1SAndroid Build Coastguard Worker struct vkr_device *dev = queue->device;
253*bbecb9d1SAndroid Build Coastguard Worker struct list_head retired_syncs;
254*bbecb9d1SAndroid Build Coastguard Worker bool queue_empty;
255*bbecb9d1SAndroid Build Coastguard Worker
256*bbecb9d1SAndroid Build Coastguard Worker vkr_queue_get_signaled_syncs(queue, &retired_syncs, &queue_empty);
257*bbecb9d1SAndroid Build Coastguard Worker
258*bbecb9d1SAndroid Build Coastguard Worker LIST_FOR_EACH_ENTRY_SAFE (sync, sync_tmp, &retired_syncs, head) {
259*bbecb9d1SAndroid Build Coastguard Worker ctx->base.fence_retire(&ctx->base, sync->ring_idx, sync->fence_id);
260*bbecb9d1SAndroid Build Coastguard Worker vkr_device_free_queue_sync(dev, sync);
261*bbecb9d1SAndroid Build Coastguard Worker }
262*bbecb9d1SAndroid Build Coastguard Worker
263*bbecb9d1SAndroid Build Coastguard Worker if (queue_empty)
264*bbecb9d1SAndroid Build Coastguard Worker list_delinit(&queue->busy_head);
265*bbecb9d1SAndroid Build Coastguard Worker }
266*bbecb9d1SAndroid Build Coastguard Worker }
267*bbecb9d1SAndroid Build Coastguard Worker
268*bbecb9d1SAndroid Build Coastguard Worker static void
vkr_context_retire_fences(struct virgl_context * base)269*bbecb9d1SAndroid Build Coastguard Worker vkr_context_retire_fences(struct virgl_context *base)
270*bbecb9d1SAndroid Build Coastguard Worker {
271*bbecb9d1SAndroid Build Coastguard Worker struct vkr_context *ctx = (struct vkr_context *)base;
272*bbecb9d1SAndroid Build Coastguard Worker
273*bbecb9d1SAndroid Build Coastguard Worker if (vkr_renderer_flags & VKR_RENDERER_ASYNC_FENCE_CB)
274*bbecb9d1SAndroid Build Coastguard Worker return;
275*bbecb9d1SAndroid Build Coastguard Worker
276*bbecb9d1SAndroid Build Coastguard Worker mtx_lock(&ctx->mutex);
277*bbecb9d1SAndroid Build Coastguard Worker vkr_context_retire_fences_locked(base);
278*bbecb9d1SAndroid Build Coastguard Worker mtx_unlock(&ctx->mutex);
279*bbecb9d1SAndroid Build Coastguard Worker }
280*bbecb9d1SAndroid Build Coastguard Worker
281*bbecb9d1SAndroid Build Coastguard Worker static int
vkr_context_get_fencing_fd(struct virgl_context * base)282*bbecb9d1SAndroid Build Coastguard Worker vkr_context_get_fencing_fd(struct virgl_context *base)
283*bbecb9d1SAndroid Build Coastguard Worker {
284*bbecb9d1SAndroid Build Coastguard Worker struct vkr_context *ctx = (struct vkr_context *)base;
285*bbecb9d1SAndroid Build Coastguard Worker return ctx->fence_eventfd;
286*bbecb9d1SAndroid Build Coastguard Worker }
287*bbecb9d1SAndroid Build Coastguard Worker
288*bbecb9d1SAndroid Build Coastguard Worker static int
vkr_context_submit_cmd(struct virgl_context * base,const void * buffer,size_t size)289*bbecb9d1SAndroid Build Coastguard Worker vkr_context_submit_cmd(struct virgl_context *base, const void *buffer, size_t size)
290*bbecb9d1SAndroid Build Coastguard Worker {
291*bbecb9d1SAndroid Build Coastguard Worker struct vkr_context *ctx = (struct vkr_context *)base;
292*bbecb9d1SAndroid Build Coastguard Worker int ret = 0;
293*bbecb9d1SAndroid Build Coastguard Worker
294*bbecb9d1SAndroid Build Coastguard Worker mtx_lock(&ctx->mutex);
295*bbecb9d1SAndroid Build Coastguard Worker
296*bbecb9d1SAndroid Build Coastguard Worker /* CS error is considered fatal (destroy the context?) */
297*bbecb9d1SAndroid Build Coastguard Worker if (vkr_cs_decoder_get_fatal(&ctx->decoder)) {
298*bbecb9d1SAndroid Build Coastguard Worker mtx_unlock(&ctx->mutex);
299*bbecb9d1SAndroid Build Coastguard Worker return -EINVAL;
300*bbecb9d1SAndroid Build Coastguard Worker }
301*bbecb9d1SAndroid Build Coastguard Worker
302*bbecb9d1SAndroid Build Coastguard Worker vkr_cs_decoder_set_stream(&ctx->decoder, buffer, size);
303*bbecb9d1SAndroid Build Coastguard Worker
304*bbecb9d1SAndroid Build Coastguard Worker while (vkr_cs_decoder_has_command(&ctx->decoder)) {
305*bbecb9d1SAndroid Build Coastguard Worker vn_dispatch_command(&ctx->dispatch);
306*bbecb9d1SAndroid Build Coastguard Worker if (vkr_cs_decoder_get_fatal(&ctx->decoder)) {
307*bbecb9d1SAndroid Build Coastguard Worker ret = -EINVAL;
308*bbecb9d1SAndroid Build Coastguard Worker break;
309*bbecb9d1SAndroid Build Coastguard Worker }
310*bbecb9d1SAndroid Build Coastguard Worker }
311*bbecb9d1SAndroid Build Coastguard Worker
312*bbecb9d1SAndroid Build Coastguard Worker vkr_cs_decoder_reset(&ctx->decoder);
313*bbecb9d1SAndroid Build Coastguard Worker
314*bbecb9d1SAndroid Build Coastguard Worker mtx_unlock(&ctx->mutex);
315*bbecb9d1SAndroid Build Coastguard Worker
316*bbecb9d1SAndroid Build Coastguard Worker return ret;
317*bbecb9d1SAndroid Build Coastguard Worker }
318*bbecb9d1SAndroid Build Coastguard Worker
319*bbecb9d1SAndroid Build Coastguard Worker static int
vkr_context_get_blob_locked(struct virgl_context * base,uint64_t blob_id,uint64_t blob_size,uint32_t flags,struct virgl_context_blob * blob)320*bbecb9d1SAndroid Build Coastguard Worker vkr_context_get_blob_locked(struct virgl_context *base,
321*bbecb9d1SAndroid Build Coastguard Worker uint64_t blob_id,
322*bbecb9d1SAndroid Build Coastguard Worker uint64_t blob_size,
323*bbecb9d1SAndroid Build Coastguard Worker uint32_t flags,
324*bbecb9d1SAndroid Build Coastguard Worker struct virgl_context_blob *blob)
325*bbecb9d1SAndroid Build Coastguard Worker {
326*bbecb9d1SAndroid Build Coastguard Worker struct vkr_context *ctx = (struct vkr_context *)base;
327*bbecb9d1SAndroid Build Coastguard Worker struct vkr_device_memory *mem;
328*bbecb9d1SAndroid Build Coastguard Worker enum virgl_resource_fd_type fd_type = VIRGL_RESOURCE_FD_INVALID;
329*bbecb9d1SAndroid Build Coastguard Worker int fd = -1;
330*bbecb9d1SAndroid Build Coastguard Worker
331*bbecb9d1SAndroid Build Coastguard Worker /* blob_id == 0 does not refer to an existing VkDeviceMemory, but implies a
332*bbecb9d1SAndroid Build Coastguard Worker * shm allocation. It serves a similar purpose as iov does, but it is
333*bbecb9d1SAndroid Build Coastguard Worker * logically contiguous and it can be exported.
334*bbecb9d1SAndroid Build Coastguard Worker */
335*bbecb9d1SAndroid Build Coastguard Worker if (!blob_id && flags == VIRGL_RENDERER_BLOB_FLAG_USE_MAPPABLE) {
336*bbecb9d1SAndroid Build Coastguard Worker fd = os_create_anonymous_file(blob_size, "vkr-shmem");
337*bbecb9d1SAndroid Build Coastguard Worker if (fd < 0)
338*bbecb9d1SAndroid Build Coastguard Worker return -ENOMEM;
339*bbecb9d1SAndroid Build Coastguard Worker
340*bbecb9d1SAndroid Build Coastguard Worker blob->type = VIRGL_RESOURCE_FD_SHM;
341*bbecb9d1SAndroid Build Coastguard Worker blob->u.fd = fd;
342*bbecb9d1SAndroid Build Coastguard Worker blob->map_info = VIRGL_RENDERER_MAP_CACHE_CACHED;
343*bbecb9d1SAndroid Build Coastguard Worker return 0;
344*bbecb9d1SAndroid Build Coastguard Worker }
345*bbecb9d1SAndroid Build Coastguard Worker
346*bbecb9d1SAndroid Build Coastguard Worker mem = vkr_context_get_object(ctx, blob_id);
347*bbecb9d1SAndroid Build Coastguard Worker if (!mem || mem->base.type != VK_OBJECT_TYPE_DEVICE_MEMORY)
348*bbecb9d1SAndroid Build Coastguard Worker return -EINVAL;
349*bbecb9d1SAndroid Build Coastguard Worker
350*bbecb9d1SAndroid Build Coastguard Worker /* a memory can only be exported once; we don't want two resources to point
351*bbecb9d1SAndroid Build Coastguard Worker * to the same storage.
352*bbecb9d1SAndroid Build Coastguard Worker */
353*bbecb9d1SAndroid Build Coastguard Worker if (mem->exported)
354*bbecb9d1SAndroid Build Coastguard Worker return -EINVAL;
355*bbecb9d1SAndroid Build Coastguard Worker
356*bbecb9d1SAndroid Build Coastguard Worker if (!mem->valid_fd_types)
357*bbecb9d1SAndroid Build Coastguard Worker return -EINVAL;
358*bbecb9d1SAndroid Build Coastguard Worker
359*bbecb9d1SAndroid Build Coastguard Worker if (flags & VIRGL_RENDERER_BLOB_FLAG_USE_MAPPABLE) {
360*bbecb9d1SAndroid Build Coastguard Worker const bool host_visible = mem->property_flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
361*bbecb9d1SAndroid Build Coastguard Worker if (!host_visible)
362*bbecb9d1SAndroid Build Coastguard Worker return -EINVAL;
363*bbecb9d1SAndroid Build Coastguard Worker }
364*bbecb9d1SAndroid Build Coastguard Worker
365*bbecb9d1SAndroid Build Coastguard Worker if (flags & VIRGL_RENDERER_BLOB_FLAG_USE_CROSS_DEVICE) {
366*bbecb9d1SAndroid Build Coastguard Worker if (!(mem->valid_fd_types & (1 << VIRGL_RESOURCE_FD_DMABUF)))
367*bbecb9d1SAndroid Build Coastguard Worker return -EINVAL;
368*bbecb9d1SAndroid Build Coastguard Worker
369*bbecb9d1SAndroid Build Coastguard Worker fd_type = VIRGL_RESOURCE_FD_DMABUF;
370*bbecb9d1SAndroid Build Coastguard Worker }
371*bbecb9d1SAndroid Build Coastguard Worker
372*bbecb9d1SAndroid Build Coastguard Worker if (fd_type == VIRGL_RESOURCE_FD_INVALID) {
373*bbecb9d1SAndroid Build Coastguard Worker /* prefer dmabuf for easier mapping? prefer opaque for performance? */
374*bbecb9d1SAndroid Build Coastguard Worker if (mem->valid_fd_types & (1 << VIRGL_RESOURCE_FD_DMABUF))
375*bbecb9d1SAndroid Build Coastguard Worker fd_type = VIRGL_RESOURCE_FD_DMABUF;
376*bbecb9d1SAndroid Build Coastguard Worker else if (mem->valid_fd_types & (1 << VIRGL_RESOURCE_FD_OPAQUE))
377*bbecb9d1SAndroid Build Coastguard Worker fd_type = VIRGL_RESOURCE_FD_OPAQUE;
378*bbecb9d1SAndroid Build Coastguard Worker }
379*bbecb9d1SAndroid Build Coastguard Worker
380*bbecb9d1SAndroid Build Coastguard Worker if (fd_type != VIRGL_RESOURCE_FD_INVALID) {
381*bbecb9d1SAndroid Build Coastguard Worker VkExternalMemoryHandleTypeFlagBits handle_type;
382*bbecb9d1SAndroid Build Coastguard Worker int ret;
383*bbecb9d1SAndroid Build Coastguard Worker
384*bbecb9d1SAndroid Build Coastguard Worker switch (fd_type) {
385*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_RESOURCE_FD_DMABUF:
386*bbecb9d1SAndroid Build Coastguard Worker handle_type = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
387*bbecb9d1SAndroid Build Coastguard Worker break;
388*bbecb9d1SAndroid Build Coastguard Worker case VIRGL_RESOURCE_FD_OPAQUE:
389*bbecb9d1SAndroid Build Coastguard Worker handle_type = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;
390*bbecb9d1SAndroid Build Coastguard Worker assert(sizeof(blob->opaque_fd_metadata.driver_uuid) == VK_UUID_SIZE);
391*bbecb9d1SAndroid Build Coastguard Worker memcpy(blob->opaque_fd_metadata.driver_uuid,
392*bbecb9d1SAndroid Build Coastguard Worker mem->device->physical_device->id_properties.driverUUID, VK_UUID_SIZE);
393*bbecb9d1SAndroid Build Coastguard Worker memcpy(blob->opaque_fd_metadata.device_uuid,
394*bbecb9d1SAndroid Build Coastguard Worker mem->device->physical_device->id_properties.deviceUUID, VK_UUID_SIZE);
395*bbecb9d1SAndroid Build Coastguard Worker blob->opaque_fd_metadata.allocation_size = mem->allocation_size;
396*bbecb9d1SAndroid Build Coastguard Worker blob->opaque_fd_metadata.memory_type_index = mem->memory_type_index;
397*bbecb9d1SAndroid Build Coastguard Worker break;
398*bbecb9d1SAndroid Build Coastguard Worker default:
399*bbecb9d1SAndroid Build Coastguard Worker return -EINVAL;
400*bbecb9d1SAndroid Build Coastguard Worker }
401*bbecb9d1SAndroid Build Coastguard Worker
402*bbecb9d1SAndroid Build Coastguard Worker ret = vkr_device_memory_export_fd(mem, handle_type, &fd);
403*bbecb9d1SAndroid Build Coastguard Worker if (ret)
404*bbecb9d1SAndroid Build Coastguard Worker return ret;
405*bbecb9d1SAndroid Build Coastguard Worker
406*bbecb9d1SAndroid Build Coastguard Worker if (fd_type == VIRGL_RESOURCE_FD_DMABUF &&
407*bbecb9d1SAndroid Build Coastguard Worker (uint64_t)lseek(fd, 0, SEEK_END) < blob_size) {
408*bbecb9d1SAndroid Build Coastguard Worker close(fd);
409*bbecb9d1SAndroid Build Coastguard Worker return -EINVAL;
410*bbecb9d1SAndroid Build Coastguard Worker }
411*bbecb9d1SAndroid Build Coastguard Worker
412*bbecb9d1SAndroid Build Coastguard Worker mem->exported = true;
413*bbecb9d1SAndroid Build Coastguard Worker }
414*bbecb9d1SAndroid Build Coastguard Worker
415*bbecb9d1SAndroid Build Coastguard Worker blob->type = fd_type;
416*bbecb9d1SAndroid Build Coastguard Worker blob->u.fd = fd;
417*bbecb9d1SAndroid Build Coastguard Worker
418*bbecb9d1SAndroid Build Coastguard Worker if (flags & VIRGL_RENDERER_BLOB_FLAG_USE_MAPPABLE) {
419*bbecb9d1SAndroid Build Coastguard Worker const bool host_coherent =
420*bbecb9d1SAndroid Build Coastguard Worker mem->property_flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
421*bbecb9d1SAndroid Build Coastguard Worker const bool host_cached = mem->property_flags & VK_MEMORY_PROPERTY_HOST_CACHED_BIT;
422*bbecb9d1SAndroid Build Coastguard Worker
423*bbecb9d1SAndroid Build Coastguard Worker /* XXX guessed */
424*bbecb9d1SAndroid Build Coastguard Worker if (host_coherent) {
425*bbecb9d1SAndroid Build Coastguard Worker blob->map_info =
426*bbecb9d1SAndroid Build Coastguard Worker host_cached ? VIRGL_RENDERER_MAP_CACHE_CACHED : VIRGL_RENDERER_MAP_CACHE_WC;
427*bbecb9d1SAndroid Build Coastguard Worker } else {
428*bbecb9d1SAndroid Build Coastguard Worker blob->map_info = VIRGL_RENDERER_MAP_CACHE_WC;
429*bbecb9d1SAndroid Build Coastguard Worker }
430*bbecb9d1SAndroid Build Coastguard Worker } else {
431*bbecb9d1SAndroid Build Coastguard Worker blob->map_info = VIRGL_RENDERER_MAP_CACHE_NONE;
432*bbecb9d1SAndroid Build Coastguard Worker }
433*bbecb9d1SAndroid Build Coastguard Worker
434*bbecb9d1SAndroid Build Coastguard Worker return 0;
435*bbecb9d1SAndroid Build Coastguard Worker }
436*bbecb9d1SAndroid Build Coastguard Worker
437*bbecb9d1SAndroid Build Coastguard Worker static int
vkr_context_get_blob(struct virgl_context * base,UNUSED uint32_t res_id,uint64_t blob_id,uint64_t blob_size,uint32_t flags,struct virgl_context_blob * blob)438*bbecb9d1SAndroid Build Coastguard Worker vkr_context_get_blob(struct virgl_context *base,
439*bbecb9d1SAndroid Build Coastguard Worker UNUSED uint32_t res_id,
440*bbecb9d1SAndroid Build Coastguard Worker uint64_t blob_id,
441*bbecb9d1SAndroid Build Coastguard Worker uint64_t blob_size,
442*bbecb9d1SAndroid Build Coastguard Worker uint32_t flags,
443*bbecb9d1SAndroid Build Coastguard Worker struct virgl_context_blob *blob)
444*bbecb9d1SAndroid Build Coastguard Worker {
445*bbecb9d1SAndroid Build Coastguard Worker struct vkr_context *ctx = (struct vkr_context *)base;
446*bbecb9d1SAndroid Build Coastguard Worker int ret;
447*bbecb9d1SAndroid Build Coastguard Worker
448*bbecb9d1SAndroid Build Coastguard Worker mtx_lock(&ctx->mutex);
449*bbecb9d1SAndroid Build Coastguard Worker ret = vkr_context_get_blob_locked(base, blob_id, blob_size, flags, blob);
450*bbecb9d1SAndroid Build Coastguard Worker mtx_unlock(&ctx->mutex);
451*bbecb9d1SAndroid Build Coastguard Worker
452*bbecb9d1SAndroid Build Coastguard Worker return ret;
453*bbecb9d1SAndroid Build Coastguard Worker }
454*bbecb9d1SAndroid Build Coastguard Worker
455*bbecb9d1SAndroid Build Coastguard Worker static int
vkr_context_transfer_3d(struct virgl_context * base,struct virgl_resource * res,UNUSED const struct vrend_transfer_info * info,UNUSED int transfer_mode)456*bbecb9d1SAndroid Build Coastguard Worker vkr_context_transfer_3d(struct virgl_context *base,
457*bbecb9d1SAndroid Build Coastguard Worker struct virgl_resource *res,
458*bbecb9d1SAndroid Build Coastguard Worker UNUSED const struct vrend_transfer_info *info,
459*bbecb9d1SAndroid Build Coastguard Worker UNUSED int transfer_mode)
460*bbecb9d1SAndroid Build Coastguard Worker {
461*bbecb9d1SAndroid Build Coastguard Worker struct vkr_context *ctx = (struct vkr_context *)base;
462*bbecb9d1SAndroid Build Coastguard Worker
463*bbecb9d1SAndroid Build Coastguard Worker vkr_log("no transfer support for ctx %d and res %d", ctx->base.ctx_id, res->res_id);
464*bbecb9d1SAndroid Build Coastguard Worker return -1;
465*bbecb9d1SAndroid Build Coastguard Worker }
466*bbecb9d1SAndroid Build Coastguard Worker
467*bbecb9d1SAndroid Build Coastguard Worker static void
vkr_context_attach_resource_locked(struct virgl_context * base,struct virgl_resource * res)468*bbecb9d1SAndroid Build Coastguard Worker vkr_context_attach_resource_locked(struct virgl_context *base, struct virgl_resource *res)
469*bbecb9d1SAndroid Build Coastguard Worker {
470*bbecb9d1SAndroid Build Coastguard Worker struct vkr_context *ctx = (struct vkr_context *)base;
471*bbecb9d1SAndroid Build Coastguard Worker struct vkr_resource_attachment *att;
472*bbecb9d1SAndroid Build Coastguard Worker
473*bbecb9d1SAndroid Build Coastguard Worker att = vkr_context_get_resource(ctx, res->res_id);
474*bbecb9d1SAndroid Build Coastguard Worker if (att) {
475*bbecb9d1SAndroid Build Coastguard Worker assert(att->resource == res);
476*bbecb9d1SAndroid Build Coastguard Worker return;
477*bbecb9d1SAndroid Build Coastguard Worker }
478*bbecb9d1SAndroid Build Coastguard Worker
479*bbecb9d1SAndroid Build Coastguard Worker att = calloc(1, sizeof(*att));
480*bbecb9d1SAndroid Build Coastguard Worker if (!att)
481*bbecb9d1SAndroid Build Coastguard Worker return;
482*bbecb9d1SAndroid Build Coastguard Worker
483*bbecb9d1SAndroid Build Coastguard Worker void *mmap_ptr = NULL;
484*bbecb9d1SAndroid Build Coastguard Worker if (res->fd_type == VIRGL_RESOURCE_FD_SHM) {
485*bbecb9d1SAndroid Build Coastguard Worker mmap_ptr =
486*bbecb9d1SAndroid Build Coastguard Worker mmap(NULL, res->map_size, PROT_WRITE | PROT_READ, MAP_SHARED, res->fd, 0);
487*bbecb9d1SAndroid Build Coastguard Worker if (mmap_ptr == MAP_FAILED) {
488*bbecb9d1SAndroid Build Coastguard Worker free(att);
489*bbecb9d1SAndroid Build Coastguard Worker return;
490*bbecb9d1SAndroid Build Coastguard Worker }
491*bbecb9d1SAndroid Build Coastguard Worker }
492*bbecb9d1SAndroid Build Coastguard Worker
493*bbecb9d1SAndroid Build Coastguard Worker att->resource = res;
494*bbecb9d1SAndroid Build Coastguard Worker
495*bbecb9d1SAndroid Build Coastguard Worker if (mmap_ptr) {
496*bbecb9d1SAndroid Build Coastguard Worker att->shm_iov.iov_base = mmap_ptr;
497*bbecb9d1SAndroid Build Coastguard Worker att->shm_iov.iov_len = res->map_size;
498*bbecb9d1SAndroid Build Coastguard Worker att->iov = &att->shm_iov;
499*bbecb9d1SAndroid Build Coastguard Worker att->iov_count = 1;
500*bbecb9d1SAndroid Build Coastguard Worker } else {
501*bbecb9d1SAndroid Build Coastguard Worker att->iov = res->iov;
502*bbecb9d1SAndroid Build Coastguard Worker att->iov_count = res->iov_count;
503*bbecb9d1SAndroid Build Coastguard Worker }
504*bbecb9d1SAndroid Build Coastguard Worker
505*bbecb9d1SAndroid Build Coastguard Worker vkr_context_add_resource(ctx, att);
506*bbecb9d1SAndroid Build Coastguard Worker }
507*bbecb9d1SAndroid Build Coastguard Worker
508*bbecb9d1SAndroid Build Coastguard Worker static void
vkr_context_attach_resource(struct virgl_context * base,struct virgl_resource * res)509*bbecb9d1SAndroid Build Coastguard Worker vkr_context_attach_resource(struct virgl_context *base, struct virgl_resource *res)
510*bbecb9d1SAndroid Build Coastguard Worker {
511*bbecb9d1SAndroid Build Coastguard Worker struct vkr_context *ctx = (struct vkr_context *)base;
512*bbecb9d1SAndroid Build Coastguard Worker mtx_lock(&ctx->mutex);
513*bbecb9d1SAndroid Build Coastguard Worker vkr_context_attach_resource_locked(base, res);
514*bbecb9d1SAndroid Build Coastguard Worker mtx_unlock(&ctx->mutex);
515*bbecb9d1SAndroid Build Coastguard Worker }
516*bbecb9d1SAndroid Build Coastguard Worker
517*bbecb9d1SAndroid Build Coastguard Worker static void
vkr_context_detach_resource(struct virgl_context * base,struct virgl_resource * res)518*bbecb9d1SAndroid Build Coastguard Worker vkr_context_detach_resource(struct virgl_context *base, struct virgl_resource *res)
519*bbecb9d1SAndroid Build Coastguard Worker {
520*bbecb9d1SAndroid Build Coastguard Worker struct vkr_context *ctx = (struct vkr_context *)base;
521*bbecb9d1SAndroid Build Coastguard Worker
522*bbecb9d1SAndroid Build Coastguard Worker mtx_lock(&ctx->mutex);
523*bbecb9d1SAndroid Build Coastguard Worker
524*bbecb9d1SAndroid Build Coastguard Worker const struct vkr_resource_attachment *att = ctx->encoder.stream.attachment;
525*bbecb9d1SAndroid Build Coastguard Worker if (att && att->resource == res) {
526*bbecb9d1SAndroid Build Coastguard Worker /* TODO vkSetReplyCommandStreamMESA should support res_id 0 to unset.
527*bbecb9d1SAndroid Build Coastguard Worker * Until then, and until we can ignore older guests, treat this as
528*bbecb9d1SAndroid Build Coastguard Worker * non-fatal
529*bbecb9d1SAndroid Build Coastguard Worker */
530*bbecb9d1SAndroid Build Coastguard Worker vkr_cs_encoder_set_stream(&ctx->encoder, NULL, 0, 0);
531*bbecb9d1SAndroid Build Coastguard Worker }
532*bbecb9d1SAndroid Build Coastguard Worker
533*bbecb9d1SAndroid Build Coastguard Worker struct vkr_ring *ring, *ring_tmp;
534*bbecb9d1SAndroid Build Coastguard Worker LIST_FOR_EACH_ENTRY_SAFE (ring, ring_tmp, &ctx->rings, head) {
535*bbecb9d1SAndroid Build Coastguard Worker if (ring->attachment->resource != res)
536*bbecb9d1SAndroid Build Coastguard Worker continue;
537*bbecb9d1SAndroid Build Coastguard Worker
538*bbecb9d1SAndroid Build Coastguard Worker vkr_cs_decoder_set_fatal(&ctx->decoder);
539*bbecb9d1SAndroid Build Coastguard Worker mtx_unlock(&ctx->mutex);
540*bbecb9d1SAndroid Build Coastguard Worker
541*bbecb9d1SAndroid Build Coastguard Worker vkr_ring_stop(ring);
542*bbecb9d1SAndroid Build Coastguard Worker
543*bbecb9d1SAndroid Build Coastguard Worker mtx_lock(&ctx->mutex);
544*bbecb9d1SAndroid Build Coastguard Worker vkr_ring_destroy(ring);
545*bbecb9d1SAndroid Build Coastguard Worker }
546*bbecb9d1SAndroid Build Coastguard Worker
547*bbecb9d1SAndroid Build Coastguard Worker if (res->fd_type == VIRGL_RESOURCE_FD_SHM) {
548*bbecb9d1SAndroid Build Coastguard Worker struct vkr_resource_attachment *att = vkr_context_get_resource(ctx, res->res_id);
549*bbecb9d1SAndroid Build Coastguard Worker if (att)
550*bbecb9d1SAndroid Build Coastguard Worker munmap(att->shm_iov.iov_base, att->shm_iov.iov_len);
551*bbecb9d1SAndroid Build Coastguard Worker }
552*bbecb9d1SAndroid Build Coastguard Worker
553*bbecb9d1SAndroid Build Coastguard Worker vkr_context_remove_resource(ctx, res->res_id);
554*bbecb9d1SAndroid Build Coastguard Worker
555*bbecb9d1SAndroid Build Coastguard Worker mtx_unlock(&ctx->mutex);
556*bbecb9d1SAndroid Build Coastguard Worker }
557*bbecb9d1SAndroid Build Coastguard Worker
558*bbecb9d1SAndroid Build Coastguard Worker static void
vkr_context_destroy(struct virgl_context * base)559*bbecb9d1SAndroid Build Coastguard Worker vkr_context_destroy(struct virgl_context *base)
560*bbecb9d1SAndroid Build Coastguard Worker {
561*bbecb9d1SAndroid Build Coastguard Worker /* TODO Move the entire teardown process to a separate thread so that the main thread
562*bbecb9d1SAndroid Build Coastguard Worker * cannot get blocked by the vkDeviceWaitIdle upon device destruction.
563*bbecb9d1SAndroid Build Coastguard Worker */
564*bbecb9d1SAndroid Build Coastguard Worker struct vkr_context *ctx = (struct vkr_context *)base;
565*bbecb9d1SAndroid Build Coastguard Worker
566*bbecb9d1SAndroid Build Coastguard Worker struct vkr_ring *ring, *ring_tmp;
567*bbecb9d1SAndroid Build Coastguard Worker LIST_FOR_EACH_ENTRY_SAFE (ring, ring_tmp, &ctx->rings, head) {
568*bbecb9d1SAndroid Build Coastguard Worker vkr_ring_stop(ring);
569*bbecb9d1SAndroid Build Coastguard Worker vkr_ring_destroy(ring);
570*bbecb9d1SAndroid Build Coastguard Worker }
571*bbecb9d1SAndroid Build Coastguard Worker
572*bbecb9d1SAndroid Build Coastguard Worker if (ctx->instance) {
573*bbecb9d1SAndroid Build Coastguard Worker vkr_log("destroying context %d (%s) with a valid instance", ctx->base.ctx_id,
574*bbecb9d1SAndroid Build Coastguard Worker vkr_context_get_name(ctx));
575*bbecb9d1SAndroid Build Coastguard Worker
576*bbecb9d1SAndroid Build Coastguard Worker vkr_instance_destroy(ctx, ctx->instance);
577*bbecb9d1SAndroid Build Coastguard Worker }
578*bbecb9d1SAndroid Build Coastguard Worker
579*bbecb9d1SAndroid Build Coastguard Worker _mesa_hash_table_destroy(ctx->resource_table, vkr_context_free_resource);
580*bbecb9d1SAndroid Build Coastguard Worker _mesa_hash_table_destroy(ctx->object_table, vkr_context_free_object);
581*bbecb9d1SAndroid Build Coastguard Worker
582*bbecb9d1SAndroid Build Coastguard Worker struct vkr_queue_sync *sync, *tmp;
583*bbecb9d1SAndroid Build Coastguard Worker LIST_FOR_EACH_ENTRY_SAFE (sync, tmp, &ctx->signaled_syncs, head)
584*bbecb9d1SAndroid Build Coastguard Worker free(sync);
585*bbecb9d1SAndroid Build Coastguard Worker
586*bbecb9d1SAndroid Build Coastguard Worker struct vkr_queue_sync *cpu_sync, *cpu_sync_tmp;
587*bbecb9d1SAndroid Build Coastguard Worker LIST_FOR_EACH_ENTRY_SAFE (cpu_sync, cpu_sync_tmp, &ctx->signaled_cpu_syncs, head)
588*bbecb9d1SAndroid Build Coastguard Worker free(cpu_sync);
589*bbecb9d1SAndroid Build Coastguard Worker
590*bbecb9d1SAndroid Build Coastguard Worker if (ctx->fence_eventfd >= 0)
591*bbecb9d1SAndroid Build Coastguard Worker close(ctx->fence_eventfd);
592*bbecb9d1SAndroid Build Coastguard Worker
593*bbecb9d1SAndroid Build Coastguard Worker vkr_cs_decoder_fini(&ctx->decoder);
594*bbecb9d1SAndroid Build Coastguard Worker
595*bbecb9d1SAndroid Build Coastguard Worker mtx_destroy(&ctx->mutex);
596*bbecb9d1SAndroid Build Coastguard Worker free(ctx->debug_name);
597*bbecb9d1SAndroid Build Coastguard Worker free(ctx);
598*bbecb9d1SAndroid Build Coastguard Worker }
599*bbecb9d1SAndroid Build Coastguard Worker
600*bbecb9d1SAndroid Build Coastguard Worker static void
vkr_context_init_base(struct vkr_context * ctx)601*bbecb9d1SAndroid Build Coastguard Worker vkr_context_init_base(struct vkr_context *ctx)
602*bbecb9d1SAndroid Build Coastguard Worker {
603*bbecb9d1SAndroid Build Coastguard Worker ctx->base.destroy = vkr_context_destroy;
604*bbecb9d1SAndroid Build Coastguard Worker ctx->base.attach_resource = vkr_context_attach_resource;
605*bbecb9d1SAndroid Build Coastguard Worker ctx->base.detach_resource = vkr_context_detach_resource;
606*bbecb9d1SAndroid Build Coastguard Worker ctx->base.transfer_3d = vkr_context_transfer_3d;
607*bbecb9d1SAndroid Build Coastguard Worker ctx->base.get_blob = vkr_context_get_blob;
608*bbecb9d1SAndroid Build Coastguard Worker ctx->base.submit_cmd = vkr_context_submit_cmd;
609*bbecb9d1SAndroid Build Coastguard Worker
610*bbecb9d1SAndroid Build Coastguard Worker ctx->base.get_fencing_fd = vkr_context_get_fencing_fd;
611*bbecb9d1SAndroid Build Coastguard Worker ctx->base.retire_fences = vkr_context_retire_fences;
612*bbecb9d1SAndroid Build Coastguard Worker ctx->base.submit_fence = vkr_context_submit_fence;
613*bbecb9d1SAndroid Build Coastguard Worker }
614*bbecb9d1SAndroid Build Coastguard Worker
615*bbecb9d1SAndroid Build Coastguard Worker static uint32_t
vkr_hash_u64(const void * key)616*bbecb9d1SAndroid Build Coastguard Worker vkr_hash_u64(const void *key)
617*bbecb9d1SAndroid Build Coastguard Worker {
618*bbecb9d1SAndroid Build Coastguard Worker return XXH32(key, sizeof(uint64_t), 0);
619*bbecb9d1SAndroid Build Coastguard Worker }
620*bbecb9d1SAndroid Build Coastguard Worker
621*bbecb9d1SAndroid Build Coastguard Worker static bool
vkr_key_u64_equal(const void * key1,const void * key2)622*bbecb9d1SAndroid Build Coastguard Worker vkr_key_u64_equal(const void *key1, const void *key2)
623*bbecb9d1SAndroid Build Coastguard Worker {
624*bbecb9d1SAndroid Build Coastguard Worker return *(const uint64_t *)key1 == *(const uint64_t *)key2;
625*bbecb9d1SAndroid Build Coastguard Worker }
626*bbecb9d1SAndroid Build Coastguard Worker
627*bbecb9d1SAndroid Build Coastguard Worker void
vkr_context_free_object(struct hash_entry * entry)628*bbecb9d1SAndroid Build Coastguard Worker vkr_context_free_object(struct hash_entry *entry)
629*bbecb9d1SAndroid Build Coastguard Worker {
630*bbecb9d1SAndroid Build Coastguard Worker struct vkr_object *obj = entry->data;
631*bbecb9d1SAndroid Build Coastguard Worker free(obj);
632*bbecb9d1SAndroid Build Coastguard Worker }
633*bbecb9d1SAndroid Build Coastguard Worker
634*bbecb9d1SAndroid Build Coastguard Worker void
vkr_context_free_resource(struct hash_entry * entry)635*bbecb9d1SAndroid Build Coastguard Worker vkr_context_free_resource(struct hash_entry *entry)
636*bbecb9d1SAndroid Build Coastguard Worker {
637*bbecb9d1SAndroid Build Coastguard Worker struct vkr_resource_attachment *att = entry->data;
638*bbecb9d1SAndroid Build Coastguard Worker free(att);
639*bbecb9d1SAndroid Build Coastguard Worker }
640*bbecb9d1SAndroid Build Coastguard Worker
641*bbecb9d1SAndroid Build Coastguard Worker struct virgl_context *
vkr_context_create(size_t debug_len,const char * debug_name)642*bbecb9d1SAndroid Build Coastguard Worker vkr_context_create(size_t debug_len, const char *debug_name)
643*bbecb9d1SAndroid Build Coastguard Worker {
644*bbecb9d1SAndroid Build Coastguard Worker struct vkr_context *ctx;
645*bbecb9d1SAndroid Build Coastguard Worker
646*bbecb9d1SAndroid Build Coastguard Worker ctx = calloc(1, sizeof(*ctx));
647*bbecb9d1SAndroid Build Coastguard Worker if (!ctx)
648*bbecb9d1SAndroid Build Coastguard Worker return NULL;
649*bbecb9d1SAndroid Build Coastguard Worker
650*bbecb9d1SAndroid Build Coastguard Worker ctx->debug_name = malloc(debug_len + 1);
651*bbecb9d1SAndroid Build Coastguard Worker if (!ctx->debug_name)
652*bbecb9d1SAndroid Build Coastguard Worker goto err_debug_name;
653*bbecb9d1SAndroid Build Coastguard Worker
654*bbecb9d1SAndroid Build Coastguard Worker memcpy(ctx->debug_name, debug_name, debug_len);
655*bbecb9d1SAndroid Build Coastguard Worker ctx->debug_name[debug_len] = '\0';
656*bbecb9d1SAndroid Build Coastguard Worker
657*bbecb9d1SAndroid Build Coastguard Worker #ifdef ENABLE_VENUS_VALIDATE
658*bbecb9d1SAndroid Build Coastguard Worker ctx->validate_level = VKR_CONTEXT_VALIDATE_ON;
659*bbecb9d1SAndroid Build Coastguard Worker ctx->validate_fatal = false; /* TODO set this to true */
660*bbecb9d1SAndroid Build Coastguard Worker #else
661*bbecb9d1SAndroid Build Coastguard Worker ctx->validate_level = VKR_CONTEXT_VALIDATE_NONE;
662*bbecb9d1SAndroid Build Coastguard Worker ctx->validate_fatal = false;
663*bbecb9d1SAndroid Build Coastguard Worker #endif
664*bbecb9d1SAndroid Build Coastguard Worker if (VKR_DEBUG(VALIDATE))
665*bbecb9d1SAndroid Build Coastguard Worker ctx->validate_level = VKR_CONTEXT_VALIDATE_FULL;
666*bbecb9d1SAndroid Build Coastguard Worker
667*bbecb9d1SAndroid Build Coastguard Worker if (mtx_init(&ctx->mutex, mtx_plain) != thrd_success)
668*bbecb9d1SAndroid Build Coastguard Worker goto err_mtx_init;
669*bbecb9d1SAndroid Build Coastguard Worker
670*bbecb9d1SAndroid Build Coastguard Worker ctx->object_table = _mesa_hash_table_create(NULL, vkr_hash_u64, vkr_key_u64_equal);
671*bbecb9d1SAndroid Build Coastguard Worker if (!ctx->object_table)
672*bbecb9d1SAndroid Build Coastguard Worker goto err_ctx_object_table;
673*bbecb9d1SAndroid Build Coastguard Worker
674*bbecb9d1SAndroid Build Coastguard Worker ctx->resource_table =
675*bbecb9d1SAndroid Build Coastguard Worker _mesa_hash_table_create(NULL, _mesa_hash_u32, _mesa_key_u32_equal);
676*bbecb9d1SAndroid Build Coastguard Worker if (!ctx->resource_table)
677*bbecb9d1SAndroid Build Coastguard Worker goto err_ctx_resource_table;
678*bbecb9d1SAndroid Build Coastguard Worker
679*bbecb9d1SAndroid Build Coastguard Worker vkr_cs_decoder_init(&ctx->decoder, ctx->object_table);
680*bbecb9d1SAndroid Build Coastguard Worker vkr_cs_encoder_init(&ctx->encoder, &ctx->decoder.fatal_error);
681*bbecb9d1SAndroid Build Coastguard Worker
682*bbecb9d1SAndroid Build Coastguard Worker vkr_context_init_base(ctx);
683*bbecb9d1SAndroid Build Coastguard Worker vkr_context_init_dispatch(ctx);
684*bbecb9d1SAndroid Build Coastguard Worker
685*bbecb9d1SAndroid Build Coastguard Worker if ((vkr_renderer_flags & VKR_RENDERER_THREAD_SYNC) &&
686*bbecb9d1SAndroid Build Coastguard Worker !(vkr_renderer_flags & VKR_RENDERER_ASYNC_FENCE_CB)) {
687*bbecb9d1SAndroid Build Coastguard Worker ctx->fence_eventfd = create_eventfd(0);
688*bbecb9d1SAndroid Build Coastguard Worker if (ctx->fence_eventfd < 0)
689*bbecb9d1SAndroid Build Coastguard Worker goto err_eventfd;
690*bbecb9d1SAndroid Build Coastguard Worker } else {
691*bbecb9d1SAndroid Build Coastguard Worker ctx->fence_eventfd = -1;
692*bbecb9d1SAndroid Build Coastguard Worker }
693*bbecb9d1SAndroid Build Coastguard Worker
694*bbecb9d1SAndroid Build Coastguard Worker list_inithead(&ctx->rings);
695*bbecb9d1SAndroid Build Coastguard Worker list_inithead(&ctx->busy_queues);
696*bbecb9d1SAndroid Build Coastguard Worker list_inithead(&ctx->signaled_syncs);
697*bbecb9d1SAndroid Build Coastguard Worker list_inithead(&ctx->signaled_cpu_syncs);
698*bbecb9d1SAndroid Build Coastguard Worker
699*bbecb9d1SAndroid Build Coastguard Worker return &ctx->base;
700*bbecb9d1SAndroid Build Coastguard Worker
701*bbecb9d1SAndroid Build Coastguard Worker err_eventfd:
702*bbecb9d1SAndroid Build Coastguard Worker _mesa_hash_table_destroy(ctx->resource_table, vkr_context_free_resource);
703*bbecb9d1SAndroid Build Coastguard Worker err_ctx_resource_table:
704*bbecb9d1SAndroid Build Coastguard Worker _mesa_hash_table_destroy(ctx->object_table, vkr_context_free_object);
705*bbecb9d1SAndroid Build Coastguard Worker err_ctx_object_table:
706*bbecb9d1SAndroid Build Coastguard Worker mtx_destroy(&ctx->mutex);
707*bbecb9d1SAndroid Build Coastguard Worker err_mtx_init:
708*bbecb9d1SAndroid Build Coastguard Worker free(ctx->debug_name);
709*bbecb9d1SAndroid Build Coastguard Worker err_debug_name:
710*bbecb9d1SAndroid Build Coastguard Worker free(ctx);
711*bbecb9d1SAndroid Build Coastguard Worker return NULL;
712*bbecb9d1SAndroid Build Coastguard Worker }
713