• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2020 Google LLC
3  * SPDX-License-Identifier: MIT
4  */
5 
6 #ifndef VKR_CONTEXT_H
7 #define VKR_CONTEXT_H
8 
9 #include "vkr_common.h"
10 
11 #include "venus-protocol/vn_protocol_renderer_defines.h"
12 #include "virgl_context.h"
13 #include "vrend_iov.h"
14 
15 #include "vkr_cs.h"
16 
17 struct virgl_resource;
18 
19 /*
20  * When a virgl_resource is attached in vkr_context_attach_resource, a
21  * vkr_resource_attachment is created.  A vkr_resource_attachment is valid
22  * until the resource it tracks is detached.
23  */
24 struct vkr_resource_attachment {
25    struct virgl_resource *resource;
26 
27    /* if VIRGL_RESOURCE_FD_SHM, this is the mapping of the shm and iov below
28     * points to this
29     */
30    struct iovec shm_iov;
31 
32    const struct iovec *iov;
33    int iov_count;
34 };
35 
36 enum vkr_context_validate_level {
37    /* no validation */
38    VKR_CONTEXT_VALIDATE_NONE,
39    /* force enabling a subset of the validation layer */
40    VKR_CONTEXT_VALIDATE_ON,
41    /* force enabling the validation layer */
42    VKR_CONTEXT_VALIDATE_FULL,
43 };
44 
45 struct vkr_cpu_sync {
46    uint32_t flags;
47    uint32_t ring_idx;
48    uint64_t fence_id;
49 
50    struct list_head head;
51 };
52 
53 struct vkr_context {
54    struct virgl_context base;
55 
56    char *debug_name;
57    enum vkr_context_validate_level validate_level;
58    bool validate_fatal;
59 
60    mtx_t mutex;
61 
62    struct list_head rings;
63    struct hash_table *object_table;
64    struct hash_table *resource_table;
65 
66    struct vkr_cs_encoder encoder;
67    struct vkr_cs_decoder decoder;
68    struct vn_dispatch_context dispatch;
69 
70    int fence_eventfd;
71    struct list_head busy_queues;
72    struct list_head signaled_syncs;
73    struct list_head signaled_cpu_syncs;
74 
75    struct vkr_queue *sync_queues[64];
76 
77    struct vkr_instance *instance;
78    char *instance_name;
79 };
80 
81 void
82 vkr_context_free_resource(struct hash_entry *entry);
83 
84 static inline void
vkr_context_add_resource(struct vkr_context * ctx,struct vkr_resource_attachment * att)85 vkr_context_add_resource(struct vkr_context *ctx, struct vkr_resource_attachment *att)
86 {
87    assert(!_mesa_hash_table_search(ctx->resource_table, &att->resource->res_id));
88    _mesa_hash_table_insert(ctx->resource_table, &att->resource->res_id, att);
89 }
90 
91 static inline void
vkr_context_remove_resource(struct vkr_context * ctx,uint32_t res_id)92 vkr_context_remove_resource(struct vkr_context *ctx, uint32_t res_id)
93 {
94    struct hash_entry *entry = _mesa_hash_table_search(ctx->resource_table, &res_id);
95    if (likely(entry)) {
96       vkr_context_free_resource(entry);
97       _mesa_hash_table_remove(ctx->resource_table, entry);
98    }
99 }
100 
101 static inline struct vkr_resource_attachment *
vkr_context_get_resource(struct vkr_context * ctx,uint32_t res_id)102 vkr_context_get_resource(struct vkr_context *ctx, uint32_t res_id)
103 {
104    const struct hash_entry *entry = _mesa_hash_table_search(ctx->resource_table, &res_id);
105    return likely(entry) ? entry->data : NULL;
106 }
107 
108 static inline bool
vkr_context_validate_object_id(struct vkr_context * ctx,vkr_object_id id)109 vkr_context_validate_object_id(struct vkr_context *ctx, vkr_object_id id)
110 {
111    if (unlikely(!id || _mesa_hash_table_search(ctx->object_table, &id))) {
112       vkr_log("invalid object id %" PRIu64, id);
113       vkr_cs_decoder_set_fatal(&ctx->decoder);
114       return false;
115    }
116 
117    return true;
118 }
119 
120 static inline void *
vkr_context_alloc_object(UNUSED struct vkr_context * ctx,size_t size,VkObjectType type,const void * id_handle)121 vkr_context_alloc_object(UNUSED struct vkr_context *ctx,
122                          size_t size,
123                          VkObjectType type,
124                          const void *id_handle)
125 {
126    const vkr_object_id id = vkr_cs_handle_load_id((const void **)id_handle, type);
127    if (!vkr_context_validate_object_id(ctx, id))
128       return NULL;
129 
130    return vkr_object_alloc(size, type, id);
131 }
132 
133 void
134 vkr_context_free_object(struct hash_entry *entry);
135 
136 static inline void
vkr_context_add_object(struct vkr_context * ctx,struct vkr_object * obj)137 vkr_context_add_object(struct vkr_context *ctx, struct vkr_object *obj)
138 {
139    assert(vkr_is_recognized_object_type(obj->type));
140    assert(obj->id);
141    assert(!_mesa_hash_table_search(ctx->object_table, &obj->id));
142 
143    _mesa_hash_table_insert(ctx->object_table, &obj->id, obj);
144 }
145 
146 static inline void
vkr_context_remove_object(struct vkr_context * ctx,struct vkr_object * obj)147 vkr_context_remove_object(struct vkr_context *ctx, struct vkr_object *obj)
148 {
149    assert(_mesa_hash_table_search(ctx->object_table, &obj->id));
150 
151    struct hash_entry *entry = _mesa_hash_table_search(ctx->object_table, &obj->id);
152    if (likely(entry)) {
153       vkr_context_free_object(entry);
154       _mesa_hash_table_remove(ctx->object_table, entry);
155    }
156 }
157 
158 static inline void
vkr_context_remove_objects(struct vkr_context * ctx,struct list_head * objects)159 vkr_context_remove_objects(struct vkr_context *ctx, struct list_head *objects)
160 {
161    struct vkr_object *obj, *tmp;
162    LIST_FOR_EACH_ENTRY_SAFE (obj, tmp, objects, track_head)
163       vkr_context_remove_object(ctx, obj);
164    /* objects should be reinitialized if to be reused */
165 }
166 
167 static inline void *
vkr_context_get_object(struct vkr_context * ctx,vkr_object_id obj_id)168 vkr_context_get_object(struct vkr_context *ctx, vkr_object_id obj_id)
169 {
170    const struct hash_entry *entry = _mesa_hash_table_search(ctx->object_table, &obj_id);
171    return likely(entry) ? entry->data : NULL;
172 }
173 
174 static inline const char *
vkr_context_get_name(const struct vkr_context * ctx)175 vkr_context_get_name(const struct vkr_context *ctx)
176 {
177    /* ctx->instance_name is the application name while ctx->debug_name is
178     * usually the guest process name or the hypervisor name.  This never
179     * returns NULL because ctx->debug_name is never NULL.
180     */
181    return ctx->instance_name ? ctx->instance_name : ctx->debug_name;
182 }
183 
184 void
185 vkr_context_add_instance(struct vkr_context *ctx,
186                          struct vkr_instance *instance,
187                          const char *name);
188 
189 void
190 vkr_context_remove_instance(struct vkr_context *ctx, struct vkr_instance *instance);
191 
192 #endif /* VKR_CONTEXT_H */
193