2 * Copyright (C) 2012-2018 Rob Clark <robclark@freedesktop.org>
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:
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
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
24 * Rob Clark <robclark@freedesktop.org>
27 #ifndef FREEDRENO_RINGBUFFER_H_
28 #define FREEDRENO_RINGBUFFER_H_
30 #include "util/u_debug.h"
32 #include "freedreno_drmif.h"
37 enum fd_ringbuffer_flags
{
39 /* Primary ringbuffer for a submit, ie. an IB1 level rb
40 * which kernel must setup RB->IB1 CP_INDIRECT_BRANCH
43 FD_RINGBUFFER_PRIMARY
= 0x1,
45 /* Hint that the stateobj will be used for streaming state
46 * that is used once or a few times and then discarded.
48 * For sub-allocation, non streaming stateobj's should be
49 * sub-allocated from a page size buffer, so one long lived
50 * state obj doesn't prevent other pages from being freed.
51 * (Ie. it would be no worse than allocating a page sized
52 * bo for each small non-streaming stateobj).
54 * But streaming stateobj's could be sub-allocated from a
55 * larger buffer to reduce the alloc/del overhead.
57 FD_RINGBUFFER_STREAMING
= 0x2,
59 /* Indicates that "growable" cmdstream can be used,
60 * consisting of multiple physical cmdstream buffers
62 FD_RINGBUFFER_GROWABLE
= 0x4,
64 /* Internal use only: */
65 _FD_RINGBUFFER_OBJECT
= 0x8,
68 /* A submit object manages/tracks all the state buildup for a "submit"
69 * ioctl to the kernel. Additionally, with the exception of long-lived
70 * non-STREAMING stateobj rb's, rb's are allocated from the submit.
72 struct fd_submit
* fd_submit_new(struct fd_pipe
*pipe
);
74 /* NOTE: all ringbuffer's create from the submit should be unref'd
75 * before destroying the submit.
77 void fd_submit_del(struct fd_submit
*submit
);
79 /* Allocate a new rb from the submit. */
80 struct fd_ringbuffer
* fd_submit_new_ringbuffer(struct fd_submit
*submit
,
81 uint32_t size
, enum fd_ringbuffer_flags flags
);
83 /* in_fence_fd: -1 for no in-fence, else fence fd
84 * out_fence_fd: NULL for no output-fence requested, else ptr to return out-fence
86 int fd_submit_flush(struct fd_submit
*submit
,
87 int in_fence_fd
, int *out_fence_fd
,
90 struct fd_ringbuffer_funcs
;
92 /* the ringbuffer object is not opaque so that OUT_RING() type stuff
93 * can be inlined. Note that users should not make assumptions about
94 * the size of this struct.
96 struct fd_ringbuffer
{
97 uint32_t *cur
, *end
, *start
;
98 const struct fd_ringbuffer_funcs
*funcs
;
100 // size or end coudl probably go away
103 enum fd_ringbuffer_flags flags
;
106 /* Allocate a new long-lived state object, not associated with
109 struct fd_ringbuffer
* fd_ringbuffer_new_object(struct fd_pipe
*pipe
,
112 struct fd_ringbuffer
*fd_ringbuffer_ref(struct fd_ringbuffer
*ring
);
113 void fd_ringbuffer_del(struct fd_ringbuffer
*ring
);
115 void fd_ringbuffer_grow(struct fd_ringbuffer
*ring
, uint32_t ndwords
);
117 static inline void fd_ringbuffer_emit(struct fd_ringbuffer
*ring
,
120 (*ring
->cur
++) = data
;
125 #define FD_RELOC_READ 0x0001
126 #define FD_RELOC_WRITE 0x0002
127 #define FD_RELOC_DUMP 0x0004
132 uint32_t orhi
; /* used for a5xx+ */
135 /* NOTE: relocs are 2 dwords on a5xx+ */
137 void fd_ringbuffer_reloc(struct fd_ringbuffer
*ring
, const struct fd_reloc
*reloc
);
138 uint32_t fd_ringbuffer_cmd_count(struct fd_ringbuffer
*ring
);
139 uint32_t fd_ringbuffer_emit_reloc_ring_full(struct fd_ringbuffer
*ring
,
140 struct fd_ringbuffer
*target
, uint32_t cmd_idx
);
142 static inline uint32_t
143 offset_bytes(void *end
, void *start
)
145 return ((char *)end
) - ((char *)start
);
148 static inline uint32_t
149 fd_ringbuffer_size(struct fd_ringbuffer
*ring
)
151 /* only really needed for stateobj ringbuffers, and won't really
152 * do what you expect for growable rb's.. so lets just restrict
153 * this to stateobj's for now:
155 debug_assert(!(ring
->flags
& FD_RINGBUFFER_GROWABLE
));
156 return offset_bytes(ring
->cur
, ring
->start
);
160 #endif /* FREEDRENO_RINGBUFFER_H_ */