• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2021 Google LLC
3  * SPDX-License-Identifier: MIT
4  */
5 
6 #ifndef VN_RING_H
7 #define VN_RING_H
8 
9 #include "vn_common.h"
10 
11 #include "vn_cs.h"
12 
13 /**
14  * A ring is a single-producer and single-consumer circular buffer.  The data
15  * in the buffer are produced and consumed in order.  An externally-defined
16  * mechanism is required for ring setup and notifications in both directions.
17  * Notifications for new data from the producer are needed only when the
18  * consumer is not actively polling, which is indicated by the ring status.
19  *
20  * For venus, the data are plain venus commands.  When a venus command is
21  * consumed from the ring's perspective, there can still be ongoing CPU and/or
22  * GPU works.  This is not an issue when the works generated by following
23  * venus commands are correctly queued after the ongoing works.  There are
24  * also venus commands that facilitate polling or waiting for ongoing works.
25  */
26 
27 /* the layout of a ring in a shmem */
28 struct vn_ring_layout {
29    size_t head_offset;
30    size_t tail_offset;
31    size_t status_offset;
32 
33    size_t buffer_offset;
34    size_t buffer_size;
35 
36    size_t extra_offset;
37    size_t extra_size;
38 
39    size_t shmem_size;
40 };
41 
42 void
43 vn_ring_get_layout(size_t buf_size,
44                    size_t extra_size,
45                    struct vn_ring_layout *layout);
46 
47 struct vn_ring *
48 vn_ring_create(struct vn_instance *instance,
49                const struct vn_ring_layout *layout,
50                uint8_t direct_order);
51 
52 void
53 vn_ring_destroy(struct vn_ring *ring);
54 
55 uint64_t
56 vn_ring_get_id(struct vn_ring *ring);
57 
58 uint32_t
59 vn_ring_load_status(const struct vn_ring *ring);
60 
61 void
62 vn_ring_unset_status_bits(struct vn_ring *ring, uint32_t mask);
63 
64 bool
65 vn_ring_get_seqno_status(struct vn_ring *ring, uint32_t seqno);
66 
67 void
68 vn_ring_wait_all(struct vn_ring *ring);
69 
70 struct vn_ring_submit_command {
71    /* empty command implies errors */
72    struct vn_cs_encoder command;
73    struct vn_cs_encoder_buffer buffer;
74    /* non-zero implies waiting */
75    size_t reply_size;
76 
77    /* when reply_size is non-zero, NULL can be returned on errors */
78    struct vn_renderer_shmem *reply_shmem;
79    struct vn_cs_decoder reply;
80 
81    /* valid when ring submission succeeds */
82    bool ring_seqno_valid;
83    uint32_t ring_seqno;
84 };
85 
86 static inline struct vn_cs_encoder *
vn_ring_submit_command_init(struct vn_ring * ring,struct vn_ring_submit_command * submit,void * cmd_data,size_t cmd_size,size_t reply_size)87 vn_ring_submit_command_init(struct vn_ring *ring,
88                             struct vn_ring_submit_command *submit,
89                             void *cmd_data,
90                             size_t cmd_size,
91                             size_t reply_size)
92 {
93    submit->buffer = VN_CS_ENCODER_BUFFER_INITIALIZER(cmd_data);
94    submit->command = VN_CS_ENCODER_INITIALIZER(&submit->buffer, cmd_size);
95 
96    submit->reply_size = reply_size;
97    submit->reply_shmem = NULL;
98 
99    submit->ring_seqno_valid = false;
100 
101    return &submit->command;
102 }
103 
104 static inline struct vn_cs_decoder *
vn_ring_get_command_reply(struct vn_ring * ring,struct vn_ring_submit_command * submit)105 vn_ring_get_command_reply(struct vn_ring *ring,
106                           struct vn_ring_submit_command *submit)
107 {
108    return submit->reply_shmem ? &submit->reply : NULL;
109 }
110 
111 void
112 vn_ring_free_command_reply(struct vn_ring *ring,
113                            struct vn_ring_submit_command *submit);
114 
115 void
116 vn_ring_submit_command(struct vn_ring *ring,
117                        struct vn_ring_submit_command *submit);
118 
119 VkResult
120 vn_ring_submit_command_simple(struct vn_ring *ring,
121                               const struct vn_cs_encoder *cs);
122 
123 #endif /* VN_RING_H */
124