xref: /aosp_15_r20/external/mesa3d/src/virtio/vulkan/vn_cs.h (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker  * Copyright 2019 Google LLC
3*61046927SAndroid Build Coastguard Worker  * SPDX-License-Identifier: MIT
4*61046927SAndroid Build Coastguard Worker  */
5*61046927SAndroid Build Coastguard Worker 
6*61046927SAndroid Build Coastguard Worker #ifndef VN_CS_H
7*61046927SAndroid Build Coastguard Worker #define VN_CS_H
8*61046927SAndroid Build Coastguard Worker 
9*61046927SAndroid Build Coastguard Worker #include "vn_common.h"
10*61046927SAndroid Build Coastguard Worker 
11*61046927SAndroid Build Coastguard Worker #include "venus-protocol/vn_protocol_driver_info.h"
12*61046927SAndroid Build Coastguard Worker 
13*61046927SAndroid Build Coastguard Worker #define VN_CS_ENCODER_BUFFER_INITIALIZER(storage)                            \
14*61046927SAndroid Build Coastguard Worker    (struct vn_cs_encoder_buffer)                                             \
15*61046927SAndroid Build Coastguard Worker    {                                                                         \
16*61046927SAndroid Build Coastguard Worker       .base = storage,                                                       \
17*61046927SAndroid Build Coastguard Worker    }
18*61046927SAndroid Build Coastguard Worker 
19*61046927SAndroid Build Coastguard Worker /* note that buffers points to an unamed local variable */
20*61046927SAndroid Build Coastguard Worker #define VN_CS_ENCODER_INITIALIZER_LOCAL(storage, size)                       \
21*61046927SAndroid Build Coastguard Worker    (struct vn_cs_encoder)                                                    \
22*61046927SAndroid Build Coastguard Worker    {                                                                         \
23*61046927SAndroid Build Coastguard Worker       .storage_type = VN_CS_ENCODER_STORAGE_POINTER,                         \
24*61046927SAndroid Build Coastguard Worker       .buffers = &VN_CS_ENCODER_BUFFER_INITIALIZER(storage),                 \
25*61046927SAndroid Build Coastguard Worker       .buffer_count = 1, .buffer_max = 1, .current_buffer_size = size,       \
26*61046927SAndroid Build Coastguard Worker       .cur = storage, .end = (const void *)(storage) + (size),               \
27*61046927SAndroid Build Coastguard Worker    }
28*61046927SAndroid Build Coastguard Worker 
29*61046927SAndroid Build Coastguard Worker #define VN_CS_ENCODER_INITIALIZER(buf, size)                                 \
30*61046927SAndroid Build Coastguard Worker    (struct vn_cs_encoder)                                                    \
31*61046927SAndroid Build Coastguard Worker    {                                                                         \
32*61046927SAndroid Build Coastguard Worker       .storage_type = VN_CS_ENCODER_STORAGE_POINTER, .buffers = (buf),       \
33*61046927SAndroid Build Coastguard Worker       .buffer_count = 1, .buffer_max = 1, .current_buffer_size = size,       \
34*61046927SAndroid Build Coastguard Worker       .cur = (buf)->base, .end = (buf)->base + (size),                       \
35*61046927SAndroid Build Coastguard Worker    }
36*61046927SAndroid Build Coastguard Worker 
37*61046927SAndroid Build Coastguard Worker #define VN_CS_DECODER_INITIALIZER(storage, size)                             \
38*61046927SAndroid Build Coastguard Worker    (struct vn_cs_decoder)                                                    \
39*61046927SAndroid Build Coastguard Worker    {                                                                         \
40*61046927SAndroid Build Coastguard Worker       .cur = storage, .end = (const void *)(storage) + (size),               \
41*61046927SAndroid Build Coastguard Worker    }
42*61046927SAndroid Build Coastguard Worker 
43*61046927SAndroid Build Coastguard Worker enum vn_cs_encoder_storage_type {
44*61046927SAndroid Build Coastguard Worker    /* a pointer to an externally-managed storage */
45*61046927SAndroid Build Coastguard Worker    VN_CS_ENCODER_STORAGE_POINTER,
46*61046927SAndroid Build Coastguard Worker    /* an array of dynamically allocated shmems */
47*61046927SAndroid Build Coastguard Worker    VN_CS_ENCODER_STORAGE_SHMEM_ARRAY,
48*61046927SAndroid Build Coastguard Worker    /* same as above, but shmems are suballocated from a pool */
49*61046927SAndroid Build Coastguard Worker    VN_CS_ENCODER_STORAGE_SHMEM_POOL,
50*61046927SAndroid Build Coastguard Worker };
51*61046927SAndroid Build Coastguard Worker 
52*61046927SAndroid Build Coastguard Worker struct vn_cs_encoder_buffer {
53*61046927SAndroid Build Coastguard Worker    struct vn_renderer_shmem *shmem;
54*61046927SAndroid Build Coastguard Worker    size_t offset;
55*61046927SAndroid Build Coastguard Worker    void *base;
56*61046927SAndroid Build Coastguard Worker    size_t committed_size;
57*61046927SAndroid Build Coastguard Worker };
58*61046927SAndroid Build Coastguard Worker 
59*61046927SAndroid Build Coastguard Worker struct vn_cs_encoder {
60*61046927SAndroid Build Coastguard Worker    struct vn_instance *instance;
61*61046927SAndroid Build Coastguard Worker    enum vn_cs_encoder_storage_type storage_type;
62*61046927SAndroid Build Coastguard Worker    size_t min_buffer_size;
63*61046927SAndroid Build Coastguard Worker 
64*61046927SAndroid Build Coastguard Worker    bool fatal_error;
65*61046927SAndroid Build Coastguard Worker 
66*61046927SAndroid Build Coastguard Worker    struct vn_cs_encoder_buffer *buffers;
67*61046927SAndroid Build Coastguard Worker    uint32_t buffer_count;
68*61046927SAndroid Build Coastguard Worker    uint32_t buffer_max;
69*61046927SAndroid Build Coastguard Worker    size_t total_committed_size;
70*61046927SAndroid Build Coastguard Worker 
71*61046927SAndroid Build Coastguard Worker    /* the current buffer is buffers[buffer_count - 1].shmem */
72*61046927SAndroid Build Coastguard Worker    size_t current_buffer_size;
73*61046927SAndroid Build Coastguard Worker 
74*61046927SAndroid Build Coastguard Worker    /* cur is the write pointer.  When cur passes end, the slow path is
75*61046927SAndroid Build Coastguard Worker     * triggered.
76*61046927SAndroid Build Coastguard Worker     */
77*61046927SAndroid Build Coastguard Worker    void *cur;
78*61046927SAndroid Build Coastguard Worker    const void *end;
79*61046927SAndroid Build Coastguard Worker };
80*61046927SAndroid Build Coastguard Worker 
81*61046927SAndroid Build Coastguard Worker struct vn_cs_decoder {
82*61046927SAndroid Build Coastguard Worker    const void *cur;
83*61046927SAndroid Build Coastguard Worker    const void *end;
84*61046927SAndroid Build Coastguard Worker };
85*61046927SAndroid Build Coastguard Worker 
86*61046927SAndroid Build Coastguard Worker struct vn_cs_renderer_protocol_info {
87*61046927SAndroid Build Coastguard Worker    simple_mtx_t mutex;
88*61046927SAndroid Build Coastguard Worker    bool init_once;
89*61046927SAndroid Build Coastguard Worker    uint32_t api_version;
90*61046927SAndroid Build Coastguard Worker    BITSET_DECLARE(extension_bitset, VN_INFO_EXTENSION_MAX_NUMBER + 1);
91*61046927SAndroid Build Coastguard Worker };
92*61046927SAndroid Build Coastguard Worker 
93*61046927SAndroid Build Coastguard Worker extern struct vn_cs_renderer_protocol_info _vn_cs_renderer_protocol_info;
94*61046927SAndroid Build Coastguard Worker 
95*61046927SAndroid Build Coastguard Worker static inline bool
vn_cs_renderer_protocol_has_api_version(uint32_t api_version)96*61046927SAndroid Build Coastguard Worker vn_cs_renderer_protocol_has_api_version(uint32_t api_version)
97*61046927SAndroid Build Coastguard Worker {
98*61046927SAndroid Build Coastguard Worker    return _vn_cs_renderer_protocol_info.api_version >= api_version;
99*61046927SAndroid Build Coastguard Worker }
100*61046927SAndroid Build Coastguard Worker 
101*61046927SAndroid Build Coastguard Worker static inline bool
vn_cs_renderer_protocol_has_extension(uint32_t ext_number)102*61046927SAndroid Build Coastguard Worker vn_cs_renderer_protocol_has_extension(uint32_t ext_number)
103*61046927SAndroid Build Coastguard Worker {
104*61046927SAndroid Build Coastguard Worker    return BITSET_TEST(_vn_cs_renderer_protocol_info.extension_bitset,
105*61046927SAndroid Build Coastguard Worker                       ext_number);
106*61046927SAndroid Build Coastguard Worker }
107*61046927SAndroid Build Coastguard Worker 
108*61046927SAndroid Build Coastguard Worker void
109*61046927SAndroid Build Coastguard Worker vn_cs_renderer_protocol_info_init(struct vn_instance *instance);
110*61046927SAndroid Build Coastguard Worker 
111*61046927SAndroid Build Coastguard Worker void
112*61046927SAndroid Build Coastguard Worker vn_cs_encoder_init(struct vn_cs_encoder *enc,
113*61046927SAndroid Build Coastguard Worker                    struct vn_instance *instance,
114*61046927SAndroid Build Coastguard Worker                    enum vn_cs_encoder_storage_type storage_type,
115*61046927SAndroid Build Coastguard Worker                    size_t min_size);
116*61046927SAndroid Build Coastguard Worker 
117*61046927SAndroid Build Coastguard Worker void
118*61046927SAndroid Build Coastguard Worker vn_cs_encoder_fini(struct vn_cs_encoder *enc);
119*61046927SAndroid Build Coastguard Worker 
120*61046927SAndroid Build Coastguard Worker void
121*61046927SAndroid Build Coastguard Worker vn_cs_encoder_reset(struct vn_cs_encoder *enc);
122*61046927SAndroid Build Coastguard Worker 
123*61046927SAndroid Build Coastguard Worker static inline void
vn_cs_encoder_set_fatal(const struct vn_cs_encoder * enc)124*61046927SAndroid Build Coastguard Worker vn_cs_encoder_set_fatal(const struct vn_cs_encoder *enc)
125*61046927SAndroid Build Coastguard Worker {
126*61046927SAndroid Build Coastguard Worker    /* This is fatal and should be treated as VK_ERROR_DEVICE_LOST or even
127*61046927SAndroid Build Coastguard Worker     * abort().  Note that vn_cs_encoder_reset does not clear this.
128*61046927SAndroid Build Coastguard Worker     */
129*61046927SAndroid Build Coastguard Worker    ((struct vn_cs_encoder *)enc)->fatal_error = true;
130*61046927SAndroid Build Coastguard Worker }
131*61046927SAndroid Build Coastguard Worker 
132*61046927SAndroid Build Coastguard Worker static inline bool
vn_cs_encoder_get_fatal(const struct vn_cs_encoder * enc)133*61046927SAndroid Build Coastguard Worker vn_cs_encoder_get_fatal(const struct vn_cs_encoder *enc)
134*61046927SAndroid Build Coastguard Worker {
135*61046927SAndroid Build Coastguard Worker    return enc->fatal_error;
136*61046927SAndroid Build Coastguard Worker }
137*61046927SAndroid Build Coastguard Worker 
138*61046927SAndroid Build Coastguard Worker static inline bool
vn_cs_encoder_is_empty(const struct vn_cs_encoder * enc)139*61046927SAndroid Build Coastguard Worker vn_cs_encoder_is_empty(const struct vn_cs_encoder *enc)
140*61046927SAndroid Build Coastguard Worker {
141*61046927SAndroid Build Coastguard Worker    return !enc->buffer_count || enc->cur == enc->buffers[0].base;
142*61046927SAndroid Build Coastguard Worker }
143*61046927SAndroid Build Coastguard Worker 
144*61046927SAndroid Build Coastguard Worker static inline size_t
vn_cs_encoder_get_len(const struct vn_cs_encoder * enc)145*61046927SAndroid Build Coastguard Worker vn_cs_encoder_get_len(const struct vn_cs_encoder *enc)
146*61046927SAndroid Build Coastguard Worker {
147*61046927SAndroid Build Coastguard Worker    if (unlikely(!enc->buffer_count))
148*61046927SAndroid Build Coastguard Worker       return 0;
149*61046927SAndroid Build Coastguard Worker 
150*61046927SAndroid Build Coastguard Worker    size_t len = enc->total_committed_size;
151*61046927SAndroid Build Coastguard Worker    const struct vn_cs_encoder_buffer *cur_buf =
152*61046927SAndroid Build Coastguard Worker       &enc->buffers[enc->buffer_count - 1];
153*61046927SAndroid Build Coastguard Worker    if (!cur_buf->committed_size)
154*61046927SAndroid Build Coastguard Worker       len += enc->cur - cur_buf->base;
155*61046927SAndroid Build Coastguard Worker    return len;
156*61046927SAndroid Build Coastguard Worker }
157*61046927SAndroid Build Coastguard Worker 
158*61046927SAndroid Build Coastguard Worker bool
159*61046927SAndroid Build Coastguard Worker vn_cs_encoder_reserve_internal(struct vn_cs_encoder *enc, size_t size);
160*61046927SAndroid Build Coastguard Worker 
161*61046927SAndroid Build Coastguard Worker /**
162*61046927SAndroid Build Coastguard Worker  * Reserve space for commands.
163*61046927SAndroid Build Coastguard Worker  */
164*61046927SAndroid Build Coastguard Worker static inline bool
vn_cs_encoder_reserve(struct vn_cs_encoder * enc,size_t size)165*61046927SAndroid Build Coastguard Worker vn_cs_encoder_reserve(struct vn_cs_encoder *enc, size_t size)
166*61046927SAndroid Build Coastguard Worker {
167*61046927SAndroid Build Coastguard Worker    if (unlikely(size > enc->end - enc->cur)) {
168*61046927SAndroid Build Coastguard Worker       if (!vn_cs_encoder_reserve_internal(enc, size)) {
169*61046927SAndroid Build Coastguard Worker          vn_cs_encoder_set_fatal(enc);
170*61046927SAndroid Build Coastguard Worker          return false;
171*61046927SAndroid Build Coastguard Worker       }
172*61046927SAndroid Build Coastguard Worker       assert(size <= enc->end - enc->cur);
173*61046927SAndroid Build Coastguard Worker    }
174*61046927SAndroid Build Coastguard Worker 
175*61046927SAndroid Build Coastguard Worker    return true;
176*61046927SAndroid Build Coastguard Worker }
177*61046927SAndroid Build Coastguard Worker 
178*61046927SAndroid Build Coastguard Worker static inline void
vn_cs_encoder_write(struct vn_cs_encoder * enc,size_t size,const void * val,size_t val_size)179*61046927SAndroid Build Coastguard Worker vn_cs_encoder_write(struct vn_cs_encoder *enc,
180*61046927SAndroid Build Coastguard Worker                     size_t size,
181*61046927SAndroid Build Coastguard Worker                     const void *val,
182*61046927SAndroid Build Coastguard Worker                     size_t val_size)
183*61046927SAndroid Build Coastguard Worker {
184*61046927SAndroid Build Coastguard Worker    assert(val_size <= size);
185*61046927SAndroid Build Coastguard Worker    assert(size <= enc->end - enc->cur);
186*61046927SAndroid Build Coastguard Worker 
187*61046927SAndroid Build Coastguard Worker    /* we should not rely on the compiler to optimize away memcpy... */
188*61046927SAndroid Build Coastguard Worker    memcpy(enc->cur, val, val_size);
189*61046927SAndroid Build Coastguard Worker    enc->cur += size;
190*61046927SAndroid Build Coastguard Worker }
191*61046927SAndroid Build Coastguard Worker 
192*61046927SAndroid Build Coastguard Worker void
193*61046927SAndroid Build Coastguard Worker vn_cs_encoder_commit(struct vn_cs_encoder *enc);
194*61046927SAndroid Build Coastguard Worker 
195*61046927SAndroid Build Coastguard Worker bool
196*61046927SAndroid Build Coastguard Worker vn_cs_encoder_needs_roundtrip(struct vn_cs_encoder *enc);
197*61046927SAndroid Build Coastguard Worker 
198*61046927SAndroid Build Coastguard Worker static inline void
vn_cs_decoder_init(struct vn_cs_decoder * dec,const void * data,size_t size)199*61046927SAndroid Build Coastguard Worker vn_cs_decoder_init(struct vn_cs_decoder *dec, const void *data, size_t size)
200*61046927SAndroid Build Coastguard Worker {
201*61046927SAndroid Build Coastguard Worker    *dec = VN_CS_DECODER_INITIALIZER(data, size);
202*61046927SAndroid Build Coastguard Worker }
203*61046927SAndroid Build Coastguard Worker 
204*61046927SAndroid Build Coastguard Worker static inline void
vn_cs_decoder_set_fatal(const struct vn_cs_decoder * dec)205*61046927SAndroid Build Coastguard Worker vn_cs_decoder_set_fatal(const struct vn_cs_decoder *dec)
206*61046927SAndroid Build Coastguard Worker {
207*61046927SAndroid Build Coastguard Worker    abort();
208*61046927SAndroid Build Coastguard Worker }
209*61046927SAndroid Build Coastguard Worker 
210*61046927SAndroid Build Coastguard Worker static inline bool
vn_cs_decoder_peek_internal(const struct vn_cs_decoder * dec,size_t size,void * val,size_t val_size)211*61046927SAndroid Build Coastguard Worker vn_cs_decoder_peek_internal(const struct vn_cs_decoder *dec,
212*61046927SAndroid Build Coastguard Worker                             size_t size,
213*61046927SAndroid Build Coastguard Worker                             void *val,
214*61046927SAndroid Build Coastguard Worker                             size_t val_size)
215*61046927SAndroid Build Coastguard Worker {
216*61046927SAndroid Build Coastguard Worker    assert(val_size <= size);
217*61046927SAndroid Build Coastguard Worker 
218*61046927SAndroid Build Coastguard Worker    if (unlikely(size > dec->end - dec->cur)) {
219*61046927SAndroid Build Coastguard Worker       vn_cs_decoder_set_fatal(dec);
220*61046927SAndroid Build Coastguard Worker       memset(val, 0, val_size);
221*61046927SAndroid Build Coastguard Worker       return false;
222*61046927SAndroid Build Coastguard Worker    }
223*61046927SAndroid Build Coastguard Worker 
224*61046927SAndroid Build Coastguard Worker    /* we should not rely on the compiler to optimize away memcpy... */
225*61046927SAndroid Build Coastguard Worker    memcpy(val, dec->cur, val_size);
226*61046927SAndroid Build Coastguard Worker    return true;
227*61046927SAndroid Build Coastguard Worker }
228*61046927SAndroid Build Coastguard Worker 
229*61046927SAndroid Build Coastguard Worker static inline void
vn_cs_decoder_read(struct vn_cs_decoder * dec,size_t size,void * val,size_t val_size)230*61046927SAndroid Build Coastguard Worker vn_cs_decoder_read(struct vn_cs_decoder *dec,
231*61046927SAndroid Build Coastguard Worker                    size_t size,
232*61046927SAndroid Build Coastguard Worker                    void *val,
233*61046927SAndroid Build Coastguard Worker                    size_t val_size)
234*61046927SAndroid Build Coastguard Worker {
235*61046927SAndroid Build Coastguard Worker    if (vn_cs_decoder_peek_internal(dec, size, val, val_size))
236*61046927SAndroid Build Coastguard Worker       dec->cur += size;
237*61046927SAndroid Build Coastguard Worker }
238*61046927SAndroid Build Coastguard Worker 
239*61046927SAndroid Build Coastguard Worker static inline void
vn_cs_decoder_peek(const struct vn_cs_decoder * dec,size_t size,void * val,size_t val_size)240*61046927SAndroid Build Coastguard Worker vn_cs_decoder_peek(const struct vn_cs_decoder *dec,
241*61046927SAndroid Build Coastguard Worker                    size_t size,
242*61046927SAndroid Build Coastguard Worker                    void *val,
243*61046927SAndroid Build Coastguard Worker                    size_t val_size)
244*61046927SAndroid Build Coastguard Worker {
245*61046927SAndroid Build Coastguard Worker    vn_cs_decoder_peek_internal(dec, size, val, val_size);
246*61046927SAndroid Build Coastguard Worker }
247*61046927SAndroid Build Coastguard Worker 
248*61046927SAndroid Build Coastguard Worker static inline vn_object_id
vn_cs_handle_load_id(const void ** handle,VkObjectType type)249*61046927SAndroid Build Coastguard Worker vn_cs_handle_load_id(const void **handle, VkObjectType type)
250*61046927SAndroid Build Coastguard Worker {
251*61046927SAndroid Build Coastguard Worker    return *handle ? vn_object_get_id(*handle, type) : 0;
252*61046927SAndroid Build Coastguard Worker }
253*61046927SAndroid Build Coastguard Worker 
254*61046927SAndroid Build Coastguard Worker static inline void
vn_cs_handle_store_id(void ** handle,vn_object_id id,VkObjectType type)255*61046927SAndroid Build Coastguard Worker vn_cs_handle_store_id(void **handle, vn_object_id id, VkObjectType type)
256*61046927SAndroid Build Coastguard Worker {
257*61046927SAndroid Build Coastguard Worker    vn_object_set_id(*handle, id, type);
258*61046927SAndroid Build Coastguard Worker }
259*61046927SAndroid Build Coastguard Worker 
260*61046927SAndroid Build Coastguard Worker #endif /* VN_CS_H */
261