• 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 
14 #include "vkr_cs.h"
15 
16 struct virgl_resource;
17 
18 /*
19  * When a virgl_resource is attached in vkr_context_attach_resource, a
20  * vkr_resource_attachment is created.  A vkr_resource_attachment is valid
21  * until the resource it tracks is detached.
22  *
23  * To support transfers to resources not backed by coherent dma-bufs, we
24  * associate a vkr_resource_attachment with a (list of) vkr_device_memory.
25  * This way, we can find a vkr_device_memory from a vkr_resource_attachment
26  * and do transfers using VkDeviceMemory.
27  */
28 struct vkr_resource_attachment {
29    struct virgl_resource *resource;
30    struct list_head memories;
31 };
32 
33 enum vkr_context_validate_level {
34    /* no validation */
35    VKR_CONTEXT_VALIDATE_NONE,
36    /* force enabling a subset of the validation layer */
37    VKR_CONTEXT_VALIDATE_ON,
38    /* force enabling the validation layer */
39    VKR_CONTEXT_VALIDATE_FULL,
40 };
41 
42 struct vkr_context {
43    struct virgl_context base;
44 
45    char *debug_name;
46    enum vkr_context_validate_level validate_level;
47    bool validate_fatal;
48 
49    mtx_t mutex;
50 
51    struct list_head rings;
52    struct util_hash_table_u64 *object_table;
53    struct util_hash_table *resource_table;
54    struct list_head newly_exported_memories;
55 
56    struct vkr_cs_encoder encoder;
57    struct vkr_cs_decoder decoder;
58    struct vn_dispatch_context dispatch;
59 
60    int fence_eventfd;
61    struct list_head busy_queues;
62    struct list_head signaled_syncs;
63 
64    struct vkr_instance *instance;
65    char *instance_name;
66 };
67 
68 static inline bool
vkr_context_validate_object_id(struct vkr_context * ctx,vkr_object_id id)69 vkr_context_validate_object_id(struct vkr_context *ctx, vkr_object_id id)
70 {
71    if (unlikely(!id || util_hash_table_get_u64(ctx->object_table, id))) {
72       vkr_cs_decoder_set_fatal(&ctx->decoder);
73       return false;
74    }
75 
76    return true;
77 }
78 
79 static inline void *
vkr_context_alloc_object(UNUSED struct vkr_context * ctx,size_t size,VkObjectType type,const void * id_handle)80 vkr_context_alloc_object(UNUSED struct vkr_context *ctx,
81                          size_t size,
82                          VkObjectType type,
83                          const void *id_handle)
84 {
85    const vkr_object_id id = vkr_cs_handle_load_id((const void **)id_handle, type);
86    if (!vkr_context_validate_object_id(ctx, id))
87       return NULL;
88 
89    return vkr_object_alloc(size, type, id);
90 }
91 
92 static inline void
vkr_context_add_object(struct vkr_context * ctx,struct vkr_object * obj)93 vkr_context_add_object(struct vkr_context *ctx, struct vkr_object *obj)
94 {
95    assert(vkr_is_recognized_object_type(obj->type));
96    assert(obj->id);
97    assert(!util_hash_table_get_u64(ctx->object_table, obj->id));
98 
99    util_hash_table_set_u64(ctx->object_table, obj->id, obj);
100 }
101 
102 static inline void
vkr_context_remove_object(struct vkr_context * ctx,struct vkr_object * obj)103 vkr_context_remove_object(struct vkr_context *ctx, struct vkr_object *obj)
104 {
105    assert(util_hash_table_get_u64(ctx->object_table, obj->id));
106 
107    /* this frees obj */
108    util_hash_table_remove_u64(ctx->object_table, obj->id);
109 }
110 
111 static inline void
vkr_context_remove_objects(struct vkr_context * ctx,struct list_head * objects)112 vkr_context_remove_objects(struct vkr_context *ctx, struct list_head *objects)
113 {
114    struct vkr_object *obj, *tmp;
115    LIST_FOR_EACH_ENTRY_SAFE (obj, tmp, objects, track_head)
116       vkr_context_remove_object(ctx, obj);
117    /* objects should be reinitialized if to be reused */
118 }
119 
120 static inline const char *
vkr_context_get_name(const struct vkr_context * ctx)121 vkr_context_get_name(const struct vkr_context *ctx)
122 {
123    /* ctx->instance_name is the application name while ctx->debug_name is
124     * usually the guest process name or the hypervisor name.  This never
125     * returns NULL because ctx->debug_name is never NULL.
126     */
127    return ctx->instance_name ? ctx->instance_name : ctx->debug_name;
128 }
129 
130 void
131 vkr_context_add_instance(struct vkr_context *ctx,
132                          struct vkr_instance *instance,
133                          const char *name);
134 
135 void
136 vkr_context_remove_instance(struct vkr_context *ctx, struct vkr_instance *instance);
137 
138 #endif /* VKR_CONTEXT_H */
139