xref: /third_party/mesa3d/src/virtio/vulkan/vn_ring.h (revision bf215546)
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/**
12 * A ring is a single-producer and single-consumer circular buffer.  The data
13 * in the buffer are produced and consumed in order.  An externally-defined
14 * mechanism is required for ring setup and notifications in both directions.
15 * Notifications for new data from the producer are needed only when the
16 * consumer is not actively polling, which is indicated by the ring status.
17 *
18 * For venus, the data are plain venus commands.  When a venus command is
19 * consumed from the ring's perspective, there can still be ongoing CPU and/or
20 * GPU works.  This is not an issue when the works generated by following
21 * venus commands are correctly queued after the ongoing works.  There are
22 * also venus commands that facilitate polling or waiting for ongoing works.
23 */
24
25/* the layout of a ring in a shmem */
26struct vn_ring_layout {
27   size_t head_offset;
28   size_t tail_offset;
29   size_t status_offset;
30
31   size_t buffer_offset;
32   size_t buffer_size;
33
34   size_t extra_offset;
35   size_t extra_size;
36
37   size_t shmem_size;
38};
39
40static_assert(ATOMIC_INT_LOCK_FREE == 2 && sizeof(atomic_uint) == 4,
41              "vn_ring_shared requires lock-free 32-bit atomic_uint");
42
43/* pointers to a ring in a BO */
44struct vn_ring_shared {
45   const volatile atomic_uint *head;
46   volatile atomic_uint *tail;
47   const volatile atomic_uint *status;
48   void *buffer;
49   void *extra;
50};
51
52struct vn_ring_submit {
53   uint32_t seqno;
54
55   struct list_head head;
56
57   /* BOs to keep alive (TODO make sure shmems are pinned) */
58   uint32_t shmem_count;
59   struct vn_renderer_shmem *shmems[];
60};
61
62struct vn_ring {
63   struct vn_renderer *renderer;
64
65   /* TODO assume large ring support and use fixed size */
66   uint32_t buffer_size;
67   uint32_t buffer_mask;
68
69   struct vn_ring_shared shared;
70   uint32_t cur;
71
72   struct list_head submits;
73   struct list_head free_submits;
74};
75
76void
77vn_ring_get_layout(size_t buf_size,
78                   size_t extra_size,
79                   struct vn_ring_layout *layout);
80
81void
82vn_ring_init(struct vn_ring *ring,
83             struct vn_renderer *renderer,
84             const struct vn_ring_layout *layout,
85             void *shared);
86
87void
88vn_ring_fini(struct vn_ring *ring);
89
90struct vn_ring_submit *
91vn_ring_get_submit(struct vn_ring *ring, uint32_t shmem_count);
92
93bool
94vn_ring_submit(struct vn_ring *ring,
95               struct vn_ring_submit *submit,
96               const struct vn_cs_encoder *cs,
97               uint32_t *seqno);
98
99void
100vn_ring_wait(const struct vn_ring *ring, uint32_t seqno);
101
102void
103vn_ring_wait_all(const struct vn_ring *ring);
104
105#endif /* VN_RING_H */
106