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 */ 26 struct 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 40 static_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 */ 44 struct 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 52 struct 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 62 struct 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 76 void 77 vn_ring_get_layout(size_t buf_size, 78 size_t extra_size, 79 struct vn_ring_layout *layout); 80 81 void 82 vn_ring_init(struct vn_ring *ring, 83 struct vn_renderer *renderer, 84 const struct vn_ring_layout *layout, 85 void *shared); 86 87 void 88 vn_ring_fini(struct vn_ring *ring); 89 90 struct vn_ring_submit * 91 vn_ring_get_submit(struct vn_ring *ring, uint32_t shmem_count); 92 93 bool 94 vn_ring_submit(struct vn_ring *ring, 95 struct vn_ring_submit *submit, 96 const struct vn_cs_encoder *cs, 97 uint32_t *seqno); 98 99 void 100 vn_ring_wait(const struct vn_ring *ring, uint32_t seqno); 101 102 void 103 vn_ring_wait_all(const struct vn_ring *ring); 104 105 #endif /* VN_RING_H */ 106