1 /* 2 * Copyright (C) 2018 Rob Clark <robclark@freedesktop.org> 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 * SOFTWARE. 22 * 23 * Authors: 24 * Rob Clark <robclark@freedesktop.org> 25 */ 26 27 #ifndef FREEDRENO_RINGBUFFER_SP_H_ 28 #define FREEDRENO_RINGBUFFER_SP_H_ 29 30 #include <assert.h> 31 #include <inttypes.h> 32 #include <pthread.h> 33 34 #include "util/hash_table.h" 35 #include "util/os_file.h" 36 #include "util/slab.h" 37 38 #include "freedreno_priv.h" 39 #include "freedreno_ringbuffer.h" 40 41 /* A "softpin" implementation of submit/ringbuffer, which lowers CPU overhead 42 * by avoiding the additional tracking necessary to build cmds/relocs tables 43 * (but still builds a bos table) 44 */ 45 46 typedef int (*flush_submit_list_fn)(struct list_head *submit_list); 47 48 struct fd_submit_sp { 49 struct fd_submit base; 50 51 DECLARE_ARRAY(struct fd_bo *, bos); 52 53 /* Keep a separate table of sub-alloc BOs.. the backing objects are 54 * tracked in the main bos table (because this is what the kernel 55 * sees), but we need to attach userspace fences to the sub-alloc'd 56 * BOs so the driver knows when they are idle 57 */ 58 DECLARE_ARRAY(struct fd_bo *, suballoc_bos); 59 60 /* maps fd_bo to idx in bos table: */ 61 struct hash_table *bo_table; 62 63 /* maps fd_bo to idx in suballoc_bos table: */ 64 struct hash_table *suballoc_bo_table; 65 66 struct slab_child_pool ring_pool; 67 68 /* Allow for sub-allocation of stateobj ring buffers (ie. sharing 69 * the same underlying bo).. 70 * 71 * We also rely on previous stateobj having been fully constructed 72 * so we can reclaim extra space at it's end. 73 */ 74 struct fd_ringbuffer *suballoc_ring; 75 76 /* Flush args, potentially attached to the last submit in the list 77 * of submits to merge: 78 */ 79 int in_fence_fd; 80 struct fd_fence *out_fence; 81 82 /* State for enqueued submits: 83 */ 84 struct list_head submit_list; /* includes this submit as last element */ 85 86 /* Used by retire_queue, if used by backend: */ 87 struct util_queue_fence retire_fence; 88 89 flush_submit_list_fn flush_submit_list; 90 91 uint32_t seqno; 92 }; 93 FD_DEFINE_CAST(fd_submit, fd_submit_sp); 94 95 /* for FD_RINGBUFFER_GROWABLE rb's, tracks the 'finalized' cmdstream buffers 96 * and sizes. Ie. a finalized buffer can have no more commands appended to 97 * it. 98 */ 99 struct fd_cmd_sp { 100 struct fd_bo *ring_bo; 101 unsigned size; 102 }; 103 104 struct fd_ringbuffer_sp { 105 struct fd_ringbuffer base; 106 107 /* for FD_RINGBUFFER_STREAMING rb's which are sub-allocated */ 108 unsigned offset; 109 110 union { 111 /* for _FD_RINGBUFFER_OBJECT case, the array of BOs referenced from 112 * this one 113 */ 114 struct { 115 struct fd_pipe *pipe; 116 DECLARE_ARRAY(struct fd_bo *, reloc_bos); 117 #ifndef NDEBUG 118 /* BOs to assert are attached to submit: */ 119 DECLARE_ARRAY(struct fd_bo *, assert_bos); 120 #endif 121 122 /** 123 * The seqno of the last submit we were emitted to. For stateobjs 124 * it is common to be re-emitted multiple times to the same submit, 125 * we can use this to detect the case. 126 */ 127 uint32_t last_submit_seqno; 128 }; 129 /* for other cases: */ 130 struct { 131 struct fd_submit *submit; 132 DECLARE_ARRAY(struct fd_cmd_sp, cmds); 133 }; 134 } u; 135 136 struct fd_bo *ring_bo; 137 }; 138 FD_DEFINE_CAST(fd_ringbuffer, fd_ringbuffer_sp); 139 140 void fd_pipe_sp_flush(struct fd_pipe *pipe, uint32_t fence); 141 uint32_t fd_submit_append_bo(struct fd_submit_sp *submit, struct fd_bo *bo); 142 struct fd_submit *fd_submit_sp_new(struct fd_pipe *pipe, 143 flush_submit_list_fn flush_submit_list); 144 void fd_pipe_sp_ringpool_init(struct fd_pipe *pipe); 145 void fd_pipe_sp_ringpool_fini(struct fd_pipe *pipe); 146 struct fd_ringbuffer *fd_ringbuffer_sp_new_object(struct fd_pipe *pipe, uint32_t size); 147 148 #endif /* FREEDRENO_RINGBUFFER_SP_H_ */ 149