1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker * Copyright © 2019 Google LLC
3*61046927SAndroid Build Coastguard Worker * SPDX-License-Identifier: MIT
4*61046927SAndroid Build Coastguard Worker */
5*61046927SAndroid Build Coastguard Worker
6*61046927SAndroid Build Coastguard Worker #ifndef TU_CS_H
7*61046927SAndroid Build Coastguard Worker #define TU_CS_H
8*61046927SAndroid Build Coastguard Worker
9*61046927SAndroid Build Coastguard Worker #include "tu_common.h"
10*61046927SAndroid Build Coastguard Worker
11*61046927SAndroid Build Coastguard Worker #include "freedreno_pm4.h"
12*61046927SAndroid Build Coastguard Worker
13*61046927SAndroid Build Coastguard Worker #include "tu_knl.h"
14*61046927SAndroid Build Coastguard Worker
15*61046927SAndroid Build Coastguard Worker /* For breadcrumbs we may open a network socket based on the envvar,
16*61046927SAndroid Build Coastguard Worker * it's not something that should be enabled by default.
17*61046927SAndroid Build Coastguard Worker */
18*61046927SAndroid Build Coastguard Worker #define TU_BREADCRUMBS_ENABLED 0
19*61046927SAndroid Build Coastguard Worker
20*61046927SAndroid Build Coastguard Worker enum tu_cs_mode
21*61046927SAndroid Build Coastguard Worker {
22*61046927SAndroid Build Coastguard Worker
23*61046927SAndroid Build Coastguard Worker /*
24*61046927SAndroid Build Coastguard Worker * A command stream in TU_CS_MODE_GROW mode grows automatically whenever it
25*61046927SAndroid Build Coastguard Worker * is full. tu_cs_begin must be called before command packet emission and
26*61046927SAndroid Build Coastguard Worker * tu_cs_end must be called after.
27*61046927SAndroid Build Coastguard Worker *
28*61046927SAndroid Build Coastguard Worker * This mode may create multiple entries internally. The entries must be
29*61046927SAndroid Build Coastguard Worker * submitted together.
30*61046927SAndroid Build Coastguard Worker */
31*61046927SAndroid Build Coastguard Worker TU_CS_MODE_GROW,
32*61046927SAndroid Build Coastguard Worker
33*61046927SAndroid Build Coastguard Worker /*
34*61046927SAndroid Build Coastguard Worker * A command stream in TU_CS_MODE_EXTERNAL mode wraps an external,
35*61046927SAndroid Build Coastguard Worker * fixed-size buffer. tu_cs_begin and tu_cs_end are optional and have no
36*61046927SAndroid Build Coastguard Worker * effect on it.
37*61046927SAndroid Build Coastguard Worker *
38*61046927SAndroid Build Coastguard Worker * This mode does not create any entry or any BO.
39*61046927SAndroid Build Coastguard Worker */
40*61046927SAndroid Build Coastguard Worker TU_CS_MODE_EXTERNAL,
41*61046927SAndroid Build Coastguard Worker
42*61046927SAndroid Build Coastguard Worker /*
43*61046927SAndroid Build Coastguard Worker * A command stream in TU_CS_MODE_SUB_STREAM mode does not support direct
44*61046927SAndroid Build Coastguard Worker * command packet emission. tu_cs_begin_sub_stream must be called to get a
45*61046927SAndroid Build Coastguard Worker * sub-stream to emit comamnd packets to. When done with the sub-stream,
46*61046927SAndroid Build Coastguard Worker * tu_cs_end_sub_stream must be called.
47*61046927SAndroid Build Coastguard Worker *
48*61046927SAndroid Build Coastguard Worker * This mode does not create any entry internally.
49*61046927SAndroid Build Coastguard Worker */
50*61046927SAndroid Build Coastguard Worker TU_CS_MODE_SUB_STREAM,
51*61046927SAndroid Build Coastguard Worker };
52*61046927SAndroid Build Coastguard Worker
53*61046927SAndroid Build Coastguard Worker struct tu_cs_entry
54*61046927SAndroid Build Coastguard Worker {
55*61046927SAndroid Build Coastguard Worker /* No ownership */
56*61046927SAndroid Build Coastguard Worker const struct tu_bo *bo;
57*61046927SAndroid Build Coastguard Worker
58*61046927SAndroid Build Coastguard Worker uint32_t size;
59*61046927SAndroid Build Coastguard Worker uint32_t offset;
60*61046927SAndroid Build Coastguard Worker };
61*61046927SAndroid Build Coastguard Worker
62*61046927SAndroid Build Coastguard Worker struct tu_cs_memory {
63*61046927SAndroid Build Coastguard Worker uint32_t *map;
64*61046927SAndroid Build Coastguard Worker uint64_t iova;
65*61046927SAndroid Build Coastguard Worker bool writeable;
66*61046927SAndroid Build Coastguard Worker };
67*61046927SAndroid Build Coastguard Worker
68*61046927SAndroid Build Coastguard Worker struct tu_draw_state {
69*61046927SAndroid Build Coastguard Worker uint64_t iova;
70*61046927SAndroid Build Coastguard Worker uint16_t size;
71*61046927SAndroid Build Coastguard Worker bool writeable;
72*61046927SAndroid Build Coastguard Worker };
73*61046927SAndroid Build Coastguard Worker
74*61046927SAndroid Build Coastguard Worker struct tu_bo_array {
75*61046927SAndroid Build Coastguard Worker struct tu_bo **bos;
76*61046927SAndroid Build Coastguard Worker uint32_t bo_count;
77*61046927SAndroid Build Coastguard Worker uint32_t bo_capacity;
78*61046927SAndroid Build Coastguard Worker uint32_t *start;
79*61046927SAndroid Build Coastguard Worker };
80*61046927SAndroid Build Coastguard Worker
81*61046927SAndroid Build Coastguard Worker #define TU_COND_EXEC_STACK_SIZE 4
82*61046927SAndroid Build Coastguard Worker
83*61046927SAndroid Build Coastguard Worker struct tu_cs
84*61046927SAndroid Build Coastguard Worker {
85*61046927SAndroid Build Coastguard Worker uint32_t *start;
86*61046927SAndroid Build Coastguard Worker uint32_t *cur;
87*61046927SAndroid Build Coastguard Worker uint32_t *reserved_end;
88*61046927SAndroid Build Coastguard Worker uint32_t *end;
89*61046927SAndroid Build Coastguard Worker const char *name;
90*61046927SAndroid Build Coastguard Worker
91*61046927SAndroid Build Coastguard Worker struct tu_device *device;
92*61046927SAndroid Build Coastguard Worker enum tu_cs_mode mode;
93*61046927SAndroid Build Coastguard Worker bool writeable;
94*61046927SAndroid Build Coastguard Worker uint32_t next_bo_size;
95*61046927SAndroid Build Coastguard Worker
96*61046927SAndroid Build Coastguard Worker struct tu_cs_entry *entries;
97*61046927SAndroid Build Coastguard Worker uint32_t entry_count;
98*61046927SAndroid Build Coastguard Worker uint32_t entry_capacity;
99*61046927SAndroid Build Coastguard Worker
100*61046927SAndroid Build Coastguard Worker struct tu_bo_array read_only, read_write;
101*61046927SAndroid Build Coastguard Worker
102*61046927SAndroid Build Coastguard Worker /* Optional BO that this CS is sub-allocated from for TU_CS_MODE_SUB_STREAM */
103*61046927SAndroid Build Coastguard Worker struct tu_bo *refcount_bo;
104*61046927SAndroid Build Coastguard Worker
105*61046927SAndroid Build Coastguard Worker /* iova that this CS starts with in TU_CS_MODE_EXTERNAL */
106*61046927SAndroid Build Coastguard Worker uint64_t external_iova;
107*61046927SAndroid Build Coastguard Worker
108*61046927SAndroid Build Coastguard Worker /* state for cond_exec_start/cond_exec_end */
109*61046927SAndroid Build Coastguard Worker uint32_t cond_stack_depth;
110*61046927SAndroid Build Coastguard Worker uint32_t cond_flags[TU_COND_EXEC_STACK_SIZE];
111*61046927SAndroid Build Coastguard Worker uint32_t *cond_dwords[TU_COND_EXEC_STACK_SIZE];
112*61046927SAndroid Build Coastguard Worker
113*61046927SAndroid Build Coastguard Worker uint32_t breadcrumb_emit_after;
114*61046927SAndroid Build Coastguard Worker };
115*61046927SAndroid Build Coastguard Worker
116*61046927SAndroid Build Coastguard Worker void
117*61046927SAndroid Build Coastguard Worker tu_breadcrumbs_init(struct tu_device *device);
118*61046927SAndroid Build Coastguard Worker
119*61046927SAndroid Build Coastguard Worker void
120*61046927SAndroid Build Coastguard Worker tu_breadcrumbs_finish(struct tu_device *device);
121*61046927SAndroid Build Coastguard Worker
122*61046927SAndroid Build Coastguard Worker void
123*61046927SAndroid Build Coastguard Worker tu_cs_init(struct tu_cs *cs,
124*61046927SAndroid Build Coastguard Worker struct tu_device *device,
125*61046927SAndroid Build Coastguard Worker enum tu_cs_mode mode,
126*61046927SAndroid Build Coastguard Worker uint32_t initial_size, const char *name);
127*61046927SAndroid Build Coastguard Worker
128*61046927SAndroid Build Coastguard Worker void
129*61046927SAndroid Build Coastguard Worker tu_cs_init_external(struct tu_cs *cs, struct tu_device *device,
130*61046927SAndroid Build Coastguard Worker uint32_t *start, uint32_t *end, uint64_t iova,
131*61046927SAndroid Build Coastguard Worker bool writeable);
132*61046927SAndroid Build Coastguard Worker
133*61046927SAndroid Build Coastguard Worker void
134*61046927SAndroid Build Coastguard Worker tu_cs_init_suballoc(struct tu_cs *cs, struct tu_device *device,
135*61046927SAndroid Build Coastguard Worker struct tu_suballoc_bo *bo);
136*61046927SAndroid Build Coastguard Worker
137*61046927SAndroid Build Coastguard Worker void
138*61046927SAndroid Build Coastguard Worker tu_cs_finish(struct tu_cs *cs);
139*61046927SAndroid Build Coastguard Worker
140*61046927SAndroid Build Coastguard Worker void
141*61046927SAndroid Build Coastguard Worker tu_cs_begin(struct tu_cs *cs);
142*61046927SAndroid Build Coastguard Worker
143*61046927SAndroid Build Coastguard Worker void
144*61046927SAndroid Build Coastguard Worker tu_cs_end(struct tu_cs *cs);
145*61046927SAndroid Build Coastguard Worker
146*61046927SAndroid Build Coastguard Worker void
147*61046927SAndroid Build Coastguard Worker tu_cs_set_writeable(struct tu_cs *cs, bool writeable);
148*61046927SAndroid Build Coastguard Worker
149*61046927SAndroid Build Coastguard Worker VkResult
150*61046927SAndroid Build Coastguard Worker tu_cs_begin_sub_stream_aligned(struct tu_cs *cs, uint32_t count,
151*61046927SAndroid Build Coastguard Worker uint32_t size, struct tu_cs *sub_cs);
152*61046927SAndroid Build Coastguard Worker
153*61046927SAndroid Build Coastguard Worker static inline VkResult
tu_cs_begin_sub_stream(struct tu_cs * cs,uint32_t size,struct tu_cs * sub_cs)154*61046927SAndroid Build Coastguard Worker tu_cs_begin_sub_stream(struct tu_cs *cs, uint32_t size, struct tu_cs *sub_cs)
155*61046927SAndroid Build Coastguard Worker {
156*61046927SAndroid Build Coastguard Worker return tu_cs_begin_sub_stream_aligned(cs, size, 1, sub_cs);
157*61046927SAndroid Build Coastguard Worker }
158*61046927SAndroid Build Coastguard Worker
159*61046927SAndroid Build Coastguard Worker
160*61046927SAndroid Build Coastguard Worker VkResult
161*61046927SAndroid Build Coastguard Worker tu_cs_alloc(struct tu_cs *cs,
162*61046927SAndroid Build Coastguard Worker uint32_t count,
163*61046927SAndroid Build Coastguard Worker uint32_t size,
164*61046927SAndroid Build Coastguard Worker struct tu_cs_memory *memory);
165*61046927SAndroid Build Coastguard Worker
166*61046927SAndroid Build Coastguard Worker struct tu_cs_entry
167*61046927SAndroid Build Coastguard Worker tu_cs_end_sub_stream(struct tu_cs *cs, struct tu_cs *sub_cs);
168*61046927SAndroid Build Coastguard Worker
169*61046927SAndroid Build Coastguard Worker static inline struct tu_draw_state
tu_cs_end_draw_state(struct tu_cs * cs,struct tu_cs * sub_cs)170*61046927SAndroid Build Coastguard Worker tu_cs_end_draw_state(struct tu_cs *cs, struct tu_cs *sub_cs)
171*61046927SAndroid Build Coastguard Worker {
172*61046927SAndroid Build Coastguard Worker struct tu_cs_entry entry = tu_cs_end_sub_stream(cs, sub_cs);
173*61046927SAndroid Build Coastguard Worker return (struct tu_draw_state) {
174*61046927SAndroid Build Coastguard Worker .iova = entry.bo->iova + entry.offset,
175*61046927SAndroid Build Coastguard Worker .size = entry.size / sizeof(uint32_t),
176*61046927SAndroid Build Coastguard Worker .writeable = sub_cs->writeable,
177*61046927SAndroid Build Coastguard Worker };
178*61046927SAndroid Build Coastguard Worker }
179*61046927SAndroid Build Coastguard Worker
180*61046927SAndroid Build Coastguard Worker VkResult
181*61046927SAndroid Build Coastguard Worker tu_cs_reserve_space(struct tu_cs *cs, uint32_t reserved_size);
182*61046927SAndroid Build Coastguard Worker
183*61046927SAndroid Build Coastguard Worker uint64_t
184*61046927SAndroid Build Coastguard Worker tu_cs_get_cur_iova(const struct tu_cs *cs);
185*61046927SAndroid Build Coastguard Worker
186*61046927SAndroid Build Coastguard Worker static inline struct tu_draw_state
tu_cs_draw_state(struct tu_cs * sub_cs,struct tu_cs * cs,uint32_t size)187*61046927SAndroid Build Coastguard Worker tu_cs_draw_state(struct tu_cs *sub_cs, struct tu_cs *cs, uint32_t size)
188*61046927SAndroid Build Coastguard Worker {
189*61046927SAndroid Build Coastguard Worker struct tu_cs_memory memory;
190*61046927SAndroid Build Coastguard Worker
191*61046927SAndroid Build Coastguard Worker /* TODO: clean this up */
192*61046927SAndroid Build Coastguard Worker tu_cs_alloc(sub_cs, size, 1, &memory);
193*61046927SAndroid Build Coastguard Worker tu_cs_init_external(cs, sub_cs->device, memory.map, memory.map + size,
194*61046927SAndroid Build Coastguard Worker memory.iova, memory.writeable);
195*61046927SAndroid Build Coastguard Worker tu_cs_begin(cs);
196*61046927SAndroid Build Coastguard Worker tu_cs_reserve_space(cs, size);
197*61046927SAndroid Build Coastguard Worker
198*61046927SAndroid Build Coastguard Worker return (struct tu_draw_state) {
199*61046927SAndroid Build Coastguard Worker .iova = memory.iova,
200*61046927SAndroid Build Coastguard Worker .size = size,
201*61046927SAndroid Build Coastguard Worker .writeable = sub_cs->writeable,
202*61046927SAndroid Build Coastguard Worker };
203*61046927SAndroid Build Coastguard Worker }
204*61046927SAndroid Build Coastguard Worker
205*61046927SAndroid Build Coastguard Worker void
206*61046927SAndroid Build Coastguard Worker tu_cs_reset(struct tu_cs *cs);
207*61046927SAndroid Build Coastguard Worker
208*61046927SAndroid Build Coastguard Worker VkResult
209*61046927SAndroid Build Coastguard Worker tu_cs_add_entries(struct tu_cs *cs, struct tu_cs *target);
210*61046927SAndroid Build Coastguard Worker
211*61046927SAndroid Build Coastguard Worker /**
212*61046927SAndroid Build Coastguard Worker * Get the size of the command packets emitted since the last call to
213*61046927SAndroid Build Coastguard Worker * tu_cs_add_entry.
214*61046927SAndroid Build Coastguard Worker */
215*61046927SAndroid Build Coastguard Worker static inline uint32_t
tu_cs_get_size(const struct tu_cs * cs)216*61046927SAndroid Build Coastguard Worker tu_cs_get_size(const struct tu_cs *cs)
217*61046927SAndroid Build Coastguard Worker {
218*61046927SAndroid Build Coastguard Worker return cs->cur - cs->start;
219*61046927SAndroid Build Coastguard Worker }
220*61046927SAndroid Build Coastguard Worker
221*61046927SAndroid Build Coastguard Worker /**
222*61046927SAndroid Build Coastguard Worker * Return true if there is no command packet emitted since the last call to
223*61046927SAndroid Build Coastguard Worker * tu_cs_add_entry.
224*61046927SAndroid Build Coastguard Worker */
225*61046927SAndroid Build Coastguard Worker static inline uint32_t
tu_cs_is_empty(const struct tu_cs * cs)226*61046927SAndroid Build Coastguard Worker tu_cs_is_empty(const struct tu_cs *cs)
227*61046927SAndroid Build Coastguard Worker {
228*61046927SAndroid Build Coastguard Worker return tu_cs_get_size(cs) == 0;
229*61046927SAndroid Build Coastguard Worker }
230*61046927SAndroid Build Coastguard Worker
231*61046927SAndroid Build Coastguard Worker /**
232*61046927SAndroid Build Coastguard Worker * Discard all entries. This allows \a cs to be reused while keeping the
233*61046927SAndroid Build Coastguard Worker * existing BOs and command packets intact.
234*61046927SAndroid Build Coastguard Worker */
235*61046927SAndroid Build Coastguard Worker static inline void
tu_cs_discard_entries(struct tu_cs * cs)236*61046927SAndroid Build Coastguard Worker tu_cs_discard_entries(struct tu_cs *cs)
237*61046927SAndroid Build Coastguard Worker {
238*61046927SAndroid Build Coastguard Worker assert(cs->mode == TU_CS_MODE_GROW);
239*61046927SAndroid Build Coastguard Worker cs->entry_count = 0;
240*61046927SAndroid Build Coastguard Worker }
241*61046927SAndroid Build Coastguard Worker
242*61046927SAndroid Build Coastguard Worker /**
243*61046927SAndroid Build Coastguard Worker * Get the size needed for tu_cs_emit_call.
244*61046927SAndroid Build Coastguard Worker */
245*61046927SAndroid Build Coastguard Worker static inline uint32_t
tu_cs_get_call_size(const struct tu_cs * cs)246*61046927SAndroid Build Coastguard Worker tu_cs_get_call_size(const struct tu_cs *cs)
247*61046927SAndroid Build Coastguard Worker {
248*61046927SAndroid Build Coastguard Worker assert(cs->mode == TU_CS_MODE_GROW);
249*61046927SAndroid Build Coastguard Worker /* each CP_INDIRECT_BUFFER needs 4 dwords */
250*61046927SAndroid Build Coastguard Worker return cs->entry_count * 4;
251*61046927SAndroid Build Coastguard Worker }
252*61046927SAndroid Build Coastguard Worker
253*61046927SAndroid Build Coastguard Worker /**
254*61046927SAndroid Build Coastguard Worker * Assert that we did not exceed the reserved space.
255*61046927SAndroid Build Coastguard Worker */
256*61046927SAndroid Build Coastguard Worker static inline void
tu_cs_sanity_check(const struct tu_cs * cs)257*61046927SAndroid Build Coastguard Worker tu_cs_sanity_check(const struct tu_cs *cs)
258*61046927SAndroid Build Coastguard Worker {
259*61046927SAndroid Build Coastguard Worker assert(cs->start <= cs->cur);
260*61046927SAndroid Build Coastguard Worker assert(cs->cur <= cs->reserved_end);
261*61046927SAndroid Build Coastguard Worker assert(cs->reserved_end <= cs->end);
262*61046927SAndroid Build Coastguard Worker }
263*61046927SAndroid Build Coastguard Worker
264*61046927SAndroid Build Coastguard Worker void
265*61046927SAndroid Build Coastguard Worker tu_cs_emit_sync_breadcrumb(struct tu_cs *cs, uint8_t opcode, uint16_t cnt);
266*61046927SAndroid Build Coastguard Worker
267*61046927SAndroid Build Coastguard Worker /**
268*61046927SAndroid Build Coastguard Worker * Emit a uint32_t value into a command stream, without boundary checking.
269*61046927SAndroid Build Coastguard Worker */
270*61046927SAndroid Build Coastguard Worker static inline void
tu_cs_emit(struct tu_cs * cs,uint32_t value)271*61046927SAndroid Build Coastguard Worker tu_cs_emit(struct tu_cs *cs, uint32_t value)
272*61046927SAndroid Build Coastguard Worker {
273*61046927SAndroid Build Coastguard Worker assert(cs->cur < cs->reserved_end);
274*61046927SAndroid Build Coastguard Worker *cs->cur = value;
275*61046927SAndroid Build Coastguard Worker ++cs->cur;
276*61046927SAndroid Build Coastguard Worker
277*61046927SAndroid Build Coastguard Worker #if TU_BREADCRUMBS_ENABLED
278*61046927SAndroid Build Coastguard Worker cs->breadcrumb_emit_after--;
279*61046927SAndroid Build Coastguard Worker if (cs->breadcrumb_emit_after == 0)
280*61046927SAndroid Build Coastguard Worker tu_cs_emit_sync_breadcrumb(cs, -1, 0);
281*61046927SAndroid Build Coastguard Worker #endif
282*61046927SAndroid Build Coastguard Worker }
283*61046927SAndroid Build Coastguard Worker
284*61046927SAndroid Build Coastguard Worker /**
285*61046927SAndroid Build Coastguard Worker * Emit an array of uint32_t into a command stream, without boundary checking.
286*61046927SAndroid Build Coastguard Worker */
287*61046927SAndroid Build Coastguard Worker static inline void
tu_cs_emit_array(struct tu_cs * cs,const uint32_t * values,uint32_t length)288*61046927SAndroid Build Coastguard Worker tu_cs_emit_array(struct tu_cs *cs, const uint32_t *values, uint32_t length)
289*61046927SAndroid Build Coastguard Worker {
290*61046927SAndroid Build Coastguard Worker assert(cs->cur + length <= cs->reserved_end);
291*61046927SAndroid Build Coastguard Worker memcpy(cs->cur, values, sizeof(uint32_t) * length);
292*61046927SAndroid Build Coastguard Worker cs->cur += length;
293*61046927SAndroid Build Coastguard Worker }
294*61046927SAndroid Build Coastguard Worker
295*61046927SAndroid Build Coastguard Worker /**
296*61046927SAndroid Build Coastguard Worker * Get the size of the remaining space in the current BO.
297*61046927SAndroid Build Coastguard Worker */
298*61046927SAndroid Build Coastguard Worker static inline uint32_t
tu_cs_get_space(const struct tu_cs * cs)299*61046927SAndroid Build Coastguard Worker tu_cs_get_space(const struct tu_cs *cs)
300*61046927SAndroid Build Coastguard Worker {
301*61046927SAndroid Build Coastguard Worker return cs->end - cs->cur;
302*61046927SAndroid Build Coastguard Worker }
303*61046927SAndroid Build Coastguard Worker
304*61046927SAndroid Build Coastguard Worker static inline void
tu_cs_reserve(struct tu_cs * cs,uint32_t reserved_size)305*61046927SAndroid Build Coastguard Worker tu_cs_reserve(struct tu_cs *cs, uint32_t reserved_size)
306*61046927SAndroid Build Coastguard Worker {
307*61046927SAndroid Build Coastguard Worker if (cs->mode != TU_CS_MODE_GROW) {
308*61046927SAndroid Build Coastguard Worker assert(tu_cs_get_space(cs) >= reserved_size);
309*61046927SAndroid Build Coastguard Worker assert(cs->reserved_end == cs->end);
310*61046927SAndroid Build Coastguard Worker return;
311*61046927SAndroid Build Coastguard Worker }
312*61046927SAndroid Build Coastguard Worker
313*61046927SAndroid Build Coastguard Worker if (tu_cs_get_space(cs) >= reserved_size &&
314*61046927SAndroid Build Coastguard Worker cs->entry_count < cs->entry_capacity) {
315*61046927SAndroid Build Coastguard Worker cs->reserved_end = cs->cur + reserved_size;
316*61046927SAndroid Build Coastguard Worker return;
317*61046927SAndroid Build Coastguard Worker }
318*61046927SAndroid Build Coastguard Worker
319*61046927SAndroid Build Coastguard Worker ASSERTED VkResult result = tu_cs_reserve_space(cs, reserved_size);
320*61046927SAndroid Build Coastguard Worker /* TODO: set this error in tu_cs and use it */
321*61046927SAndroid Build Coastguard Worker assert(result == VK_SUCCESS);
322*61046927SAndroid Build Coastguard Worker }
323*61046927SAndroid Build Coastguard Worker
324*61046927SAndroid Build Coastguard Worker /**
325*61046927SAndroid Build Coastguard Worker * Emit a type-4 command packet header into a command stream.
326*61046927SAndroid Build Coastguard Worker */
327*61046927SAndroid Build Coastguard Worker static inline void
tu_cs_emit_pkt4(struct tu_cs * cs,uint16_t regindx,uint16_t cnt)328*61046927SAndroid Build Coastguard Worker tu_cs_emit_pkt4(struct tu_cs *cs, uint16_t regindx, uint16_t cnt)
329*61046927SAndroid Build Coastguard Worker {
330*61046927SAndroid Build Coastguard Worker tu_cs_reserve(cs, cnt + 1);
331*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, pm4_pkt4_hdr(regindx, cnt));
332*61046927SAndroid Build Coastguard Worker }
333*61046927SAndroid Build Coastguard Worker
334*61046927SAndroid Build Coastguard Worker /**
335*61046927SAndroid Build Coastguard Worker * Emit a type-7 command packet header into a command stream.
336*61046927SAndroid Build Coastguard Worker */
337*61046927SAndroid Build Coastguard Worker static inline void
tu_cs_emit_pkt7(struct tu_cs * cs,uint8_t opcode,uint16_t cnt)338*61046927SAndroid Build Coastguard Worker tu_cs_emit_pkt7(struct tu_cs *cs, uint8_t opcode, uint16_t cnt)
339*61046927SAndroid Build Coastguard Worker {
340*61046927SAndroid Build Coastguard Worker #if TU_BREADCRUMBS_ENABLED
341*61046927SAndroid Build Coastguard Worker tu_cs_emit_sync_breadcrumb(cs, opcode, cnt + 1);
342*61046927SAndroid Build Coastguard Worker #endif
343*61046927SAndroid Build Coastguard Worker
344*61046927SAndroid Build Coastguard Worker tu_cs_reserve(cs, cnt + 1);
345*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, pm4_pkt7_hdr(opcode, cnt));
346*61046927SAndroid Build Coastguard Worker }
347*61046927SAndroid Build Coastguard Worker
348*61046927SAndroid Build Coastguard Worker static inline void
tu_cs_emit_wfi(struct tu_cs * cs)349*61046927SAndroid Build Coastguard Worker tu_cs_emit_wfi(struct tu_cs *cs)
350*61046927SAndroid Build Coastguard Worker {
351*61046927SAndroid Build Coastguard Worker tu_cs_emit_pkt7(cs, CP_WAIT_FOR_IDLE, 0);
352*61046927SAndroid Build Coastguard Worker }
353*61046927SAndroid Build Coastguard Worker
354*61046927SAndroid Build Coastguard Worker static inline void
tu_cs_emit_qw(struct tu_cs * cs,uint64_t value)355*61046927SAndroid Build Coastguard Worker tu_cs_emit_qw(struct tu_cs *cs, uint64_t value)
356*61046927SAndroid Build Coastguard Worker {
357*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, (uint32_t) value);
358*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, (uint32_t) (value >> 32));
359*61046927SAndroid Build Coastguard Worker }
360*61046927SAndroid Build Coastguard Worker
361*61046927SAndroid Build Coastguard Worker static inline void
tu_cs_emit_write_reg(struct tu_cs * cs,uint16_t reg,uint32_t value)362*61046927SAndroid Build Coastguard Worker tu_cs_emit_write_reg(struct tu_cs *cs, uint16_t reg, uint32_t value)
363*61046927SAndroid Build Coastguard Worker {
364*61046927SAndroid Build Coastguard Worker tu_cs_emit_pkt4(cs, reg, 1);
365*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, value);
366*61046927SAndroid Build Coastguard Worker }
367*61046927SAndroid Build Coastguard Worker
368*61046927SAndroid Build Coastguard Worker /**
369*61046927SAndroid Build Coastguard Worker * Emit a CP_INDIRECT_BUFFER command packet.
370*61046927SAndroid Build Coastguard Worker */
371*61046927SAndroid Build Coastguard Worker static inline void
tu_cs_emit_ib(struct tu_cs * cs,const struct tu_cs_entry * entry)372*61046927SAndroid Build Coastguard Worker tu_cs_emit_ib(struct tu_cs *cs, const struct tu_cs_entry *entry)
373*61046927SAndroid Build Coastguard Worker {
374*61046927SAndroid Build Coastguard Worker assert(entry->bo);
375*61046927SAndroid Build Coastguard Worker assert(entry->size && entry->offset + entry->size <= entry->bo->size);
376*61046927SAndroid Build Coastguard Worker assert(entry->size % sizeof(uint32_t) == 0);
377*61046927SAndroid Build Coastguard Worker assert(entry->offset % sizeof(uint32_t) == 0);
378*61046927SAndroid Build Coastguard Worker
379*61046927SAndroid Build Coastguard Worker tu_cs_emit_pkt7(cs, CP_INDIRECT_BUFFER, 3);
380*61046927SAndroid Build Coastguard Worker tu_cs_emit_qw(cs, entry->bo->iova + entry->offset);
381*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, entry->size / sizeof(uint32_t));
382*61046927SAndroid Build Coastguard Worker }
383*61046927SAndroid Build Coastguard Worker
384*61046927SAndroid Build Coastguard Worker /* for compute which isn't using SET_DRAW_STATE */
385*61046927SAndroid Build Coastguard Worker static inline void
tu_cs_emit_state_ib(struct tu_cs * cs,struct tu_draw_state state)386*61046927SAndroid Build Coastguard Worker tu_cs_emit_state_ib(struct tu_cs *cs, struct tu_draw_state state)
387*61046927SAndroid Build Coastguard Worker {
388*61046927SAndroid Build Coastguard Worker if (state.size) {
389*61046927SAndroid Build Coastguard Worker tu_cs_emit_pkt7(cs, CP_INDIRECT_BUFFER, 3);
390*61046927SAndroid Build Coastguard Worker tu_cs_emit_qw(cs, state.iova);
391*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, state.size);
392*61046927SAndroid Build Coastguard Worker }
393*61046927SAndroid Build Coastguard Worker }
394*61046927SAndroid Build Coastguard Worker
395*61046927SAndroid Build Coastguard Worker /**
396*61046927SAndroid Build Coastguard Worker * Emit a CP_INDIRECT_BUFFER command packet for each entry in the target
397*61046927SAndroid Build Coastguard Worker * command stream.
398*61046927SAndroid Build Coastguard Worker */
399*61046927SAndroid Build Coastguard Worker static inline void
tu_cs_emit_call(struct tu_cs * cs,const struct tu_cs * target)400*61046927SAndroid Build Coastguard Worker tu_cs_emit_call(struct tu_cs *cs, const struct tu_cs *target)
401*61046927SAndroid Build Coastguard Worker {
402*61046927SAndroid Build Coastguard Worker assert(target->mode == TU_CS_MODE_GROW);
403*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < target->entry_count; i++)
404*61046927SAndroid Build Coastguard Worker tu_cs_emit_ib(cs, target->entries + i);
405*61046927SAndroid Build Coastguard Worker }
406*61046927SAndroid Build Coastguard Worker
407*61046927SAndroid Build Coastguard Worker /**
408*61046927SAndroid Build Coastguard Worker * Emit a CP_NOP with a string tail into the command stream.
409*61046927SAndroid Build Coastguard Worker */
410*61046927SAndroid Build Coastguard Worker void
411*61046927SAndroid Build Coastguard Worker tu_cs_emit_debug_string(struct tu_cs *cs, const char *string, int len);
412*61046927SAndroid Build Coastguard Worker
413*61046927SAndroid Build Coastguard Worker void
414*61046927SAndroid Build Coastguard Worker tu_cs_emit_debug_magic_strv(struct tu_cs *cs,
415*61046927SAndroid Build Coastguard Worker uint32_t magic,
416*61046927SAndroid Build Coastguard Worker const char *fmt,
417*61046927SAndroid Build Coastguard Worker va_list args);
418*61046927SAndroid Build Coastguard Worker
419*61046927SAndroid Build Coastguard Worker __attribute__((format(printf, 2, 3))) void
420*61046927SAndroid Build Coastguard Worker tu_cs_emit_debug_msg(struct tu_cs *cs, const char *fmt, ...);
421*61046927SAndroid Build Coastguard Worker
422*61046927SAndroid Build Coastguard Worker /**
423*61046927SAndroid Build Coastguard Worker * Emit a single message into the CS that denote the calling function and any
424*61046927SAndroid Build Coastguard Worker * optional printf-style parameters when utrace markers are enabled.
425*61046927SAndroid Build Coastguard Worker */
426*61046927SAndroid Build Coastguard Worker #define TU_CS_DEBUG_MSG(CS, FORMAT_STRING, ...) \
427*61046927SAndroid Build Coastguard Worker do { \
428*61046927SAndroid Build Coastguard Worker if (unlikely(u_trace_markers_enabled(&(CS)->device->trace_context))) \
429*61046927SAndroid Build Coastguard Worker tu_cs_emit_debug_msg(CS, "%s(" FORMAT_STRING ")", __func__, \
430*61046927SAndroid Build Coastguard Worker ## __VA_ARGS__); \
431*61046927SAndroid Build Coastguard Worker } while (0)
432*61046927SAndroid Build Coastguard Worker
433*61046927SAndroid Build Coastguard Worker typedef struct tu_cs *tu_debug_scope;
434*61046927SAndroid Build Coastguard Worker
435*61046927SAndroid Build Coastguard Worker __attribute__((format(printf, 3, 4))) void
436*61046927SAndroid Build Coastguard Worker tu_cs_trace_start(struct u_trace_context *utctx,
437*61046927SAndroid Build Coastguard Worker void *cs,
438*61046927SAndroid Build Coastguard Worker const char *fmt,
439*61046927SAndroid Build Coastguard Worker ...);
440*61046927SAndroid Build Coastguard Worker
441*61046927SAndroid Build Coastguard Worker __attribute__((format(printf, 3, 4))) void
442*61046927SAndroid Build Coastguard Worker tu_cs_trace_end(struct u_trace_context *utctx, void *cs, const char *fmt, ...);
443*61046927SAndroid Build Coastguard Worker
444*61046927SAndroid Build Coastguard Worker /* Helpers for bracketing a large sequence of commands of unknown size inside
445*61046927SAndroid Build Coastguard Worker * a CP_COND_REG_EXEC packet.
446*61046927SAndroid Build Coastguard Worker */
447*61046927SAndroid Build Coastguard Worker static inline void
tu_cond_exec_start(struct tu_cs * cs,uint32_t cond_flags)448*61046927SAndroid Build Coastguard Worker tu_cond_exec_start(struct tu_cs *cs, uint32_t cond_flags)
449*61046927SAndroid Build Coastguard Worker {
450*61046927SAndroid Build Coastguard Worker assert(cs->mode == TU_CS_MODE_GROW);
451*61046927SAndroid Build Coastguard Worker assert(cs->cond_stack_depth < TU_COND_EXEC_STACK_SIZE);
452*61046927SAndroid Build Coastguard Worker
453*61046927SAndroid Build Coastguard Worker ASSERTED enum compare_mode mode =
454*61046927SAndroid Build Coastguard Worker (enum compare_mode)((cond_flags & CP_COND_REG_EXEC_0_MODE__MASK) >>
455*61046927SAndroid Build Coastguard Worker CP_COND_REG_EXEC_0_MODE__SHIFT);
456*61046927SAndroid Build Coastguard Worker assert(mode == PRED_TEST || mode == RENDER_MODE || mode == THREAD_MODE);
457*61046927SAndroid Build Coastguard Worker
458*61046927SAndroid Build Coastguard Worker tu_cs_emit_pkt7(cs, CP_COND_REG_EXEC, 2);
459*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, cond_flags);
460*61046927SAndroid Build Coastguard Worker
461*61046927SAndroid Build Coastguard Worker cs->cond_flags[cs->cond_stack_depth] = cond_flags;
462*61046927SAndroid Build Coastguard Worker cs->cond_dwords[cs->cond_stack_depth] = cs->cur;
463*61046927SAndroid Build Coastguard Worker
464*61046927SAndroid Build Coastguard Worker /* Emit dummy DWORD field here */
465*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, RENDER_MODE_CP_COND_REG_EXEC_1_DWORDS(0));
466*61046927SAndroid Build Coastguard Worker
467*61046927SAndroid Build Coastguard Worker cs->cond_stack_depth++;
468*61046927SAndroid Build Coastguard Worker }
469*61046927SAndroid Build Coastguard Worker #define CP_COND_EXEC_0_RENDER_MODE_GMEM \
470*61046927SAndroid Build Coastguard Worker (CP_COND_REG_EXEC_0_MODE(RENDER_MODE) | CP_COND_REG_EXEC_0_GMEM)
471*61046927SAndroid Build Coastguard Worker #define CP_COND_EXEC_0_RENDER_MODE_SYSMEM \
472*61046927SAndroid Build Coastguard Worker (CP_COND_REG_EXEC_0_MODE(RENDER_MODE) | CP_COND_REG_EXEC_0_SYSMEM)
473*61046927SAndroid Build Coastguard Worker
474*61046927SAndroid Build Coastguard Worker static inline void
tu_cond_exec_end(struct tu_cs * cs)475*61046927SAndroid Build Coastguard Worker tu_cond_exec_end(struct tu_cs *cs)
476*61046927SAndroid Build Coastguard Worker {
477*61046927SAndroid Build Coastguard Worker assert(cs->cond_stack_depth > 0);
478*61046927SAndroid Build Coastguard Worker cs->cond_stack_depth--;
479*61046927SAndroid Build Coastguard Worker
480*61046927SAndroid Build Coastguard Worker cs->cond_flags[cs->cond_stack_depth] = 0;
481*61046927SAndroid Build Coastguard Worker /* Subtract one here to account for the DWORD field itself. */
482*61046927SAndroid Build Coastguard Worker uint32_t cond_len = cs->cur - cs->cond_dwords[cs->cond_stack_depth] - 1;
483*61046927SAndroid Build Coastguard Worker if (cond_len) {
484*61046927SAndroid Build Coastguard Worker *cs->cond_dwords[cs->cond_stack_depth] = cond_len;
485*61046927SAndroid Build Coastguard Worker } else {
486*61046927SAndroid Build Coastguard Worker /* rewind the CS to drop the empty cond reg packet. */
487*61046927SAndroid Build Coastguard Worker cs->cur = cs->cur - 3;
488*61046927SAndroid Build Coastguard Worker }
489*61046927SAndroid Build Coastguard Worker }
490*61046927SAndroid Build Coastguard Worker
491*61046927SAndroid Build Coastguard Worker uint64_t
492*61046927SAndroid Build Coastguard Worker tu_cs_emit_data_nop(struct tu_cs *cs,
493*61046927SAndroid Build Coastguard Worker const uint32_t *data,
494*61046927SAndroid Build Coastguard Worker uint32_t size,
495*61046927SAndroid Build Coastguard Worker uint32_t align);
496*61046927SAndroid Build Coastguard Worker
497*61046927SAndroid Build Coastguard Worker /* Temporary struct for tracking a register state to be written, used by
498*61046927SAndroid Build Coastguard Worker * a6xx-pack.h and tu_cs_emit_regs()
499*61046927SAndroid Build Coastguard Worker */
500*61046927SAndroid Build Coastguard Worker struct tu_reg_value {
501*61046927SAndroid Build Coastguard Worker uint32_t reg;
502*61046927SAndroid Build Coastguard Worker uint64_t value;
503*61046927SAndroid Build Coastguard Worker struct tu_bo *bo;
504*61046927SAndroid Build Coastguard Worker bool is_address;
505*61046927SAndroid Build Coastguard Worker bool bo_write;
506*61046927SAndroid Build Coastguard Worker uint32_t bo_offset;
507*61046927SAndroid Build Coastguard Worker uint32_t bo_shift;
508*61046927SAndroid Build Coastguard Worker uint32_t bo_low;
509*61046927SAndroid Build Coastguard Worker };
510*61046927SAndroid Build Coastguard Worker
511*61046927SAndroid Build Coastguard Worker #define fd_reg_pair tu_reg_value
512*61046927SAndroid Build Coastguard Worker #define __bo_type struct tu_bo *
513*61046927SAndroid Build Coastguard Worker
514*61046927SAndroid Build Coastguard Worker #include "a6xx-pack.xml.h"
515*61046927SAndroid Build Coastguard Worker #include "adreno-pm4-pack.xml.h"
516*61046927SAndroid Build Coastguard Worker
517*61046927SAndroid Build Coastguard Worker #define __assert_eq(a, b) \
518*61046927SAndroid Build Coastguard Worker do { \
519*61046927SAndroid Build Coastguard Worker if ((a) != (b)) { \
520*61046927SAndroid Build Coastguard Worker fprintf(stderr, "assert failed: " #a " (0x%x) != " #b " (0x%x)\n", a, b); \
521*61046927SAndroid Build Coastguard Worker assert((a) == (b)); \
522*61046927SAndroid Build Coastguard Worker } \
523*61046927SAndroid Build Coastguard Worker } while (0)
524*61046927SAndroid Build Coastguard Worker
525*61046927SAndroid Build Coastguard Worker #define __ONE_REG(i, regs) \
526*61046927SAndroid Build Coastguard Worker do { \
527*61046927SAndroid Build Coastguard Worker if (i < ARRAY_SIZE(regs) && regs[i].reg > 0) { \
528*61046927SAndroid Build Coastguard Worker __assert_eq(regs[0].reg + i, regs[i].reg); \
529*61046927SAndroid Build Coastguard Worker if (regs[i].bo) { \
530*61046927SAndroid Build Coastguard Worker uint64_t v = regs[i].bo->iova + regs[i].bo_offset; \
531*61046927SAndroid Build Coastguard Worker v >>= regs[i].bo_shift; \
532*61046927SAndroid Build Coastguard Worker v <<= regs[i].bo_low; \
533*61046927SAndroid Build Coastguard Worker v |= regs[i].value; \
534*61046927SAndroid Build Coastguard Worker \
535*61046927SAndroid Build Coastguard Worker *p++ = v; \
536*61046927SAndroid Build Coastguard Worker *p++ = v >> 32; \
537*61046927SAndroid Build Coastguard Worker } else { \
538*61046927SAndroid Build Coastguard Worker *p++ = regs[i].value; \
539*61046927SAndroid Build Coastguard Worker if (regs[i].is_address) \
540*61046927SAndroid Build Coastguard Worker *p++ = regs[i].value >> 32; \
541*61046927SAndroid Build Coastguard Worker } \
542*61046927SAndroid Build Coastguard Worker } \
543*61046927SAndroid Build Coastguard Worker } while (0)
544*61046927SAndroid Build Coastguard Worker
545*61046927SAndroid Build Coastguard Worker /* Emits a sequence of register writes in order using a pkt4. This will check
546*61046927SAndroid Build Coastguard Worker * (at runtime on a !NDEBUG build) that the registers were actually set up in
547*61046927SAndroid Build Coastguard Worker * order in the code.
548*61046927SAndroid Build Coastguard Worker *
549*61046927SAndroid Build Coastguard Worker * Note that references to buffers aren't automatically added to the CS,
550*61046927SAndroid Build Coastguard Worker * unlike in freedreno. We are clever in various places to avoid duplicating
551*61046927SAndroid Build Coastguard Worker * the reference add work.
552*61046927SAndroid Build Coastguard Worker *
553*61046927SAndroid Build Coastguard Worker * Also, 64-bit address registers don't have a way (currently) to set a 64-bit
554*61046927SAndroid Build Coastguard Worker * address without having a reference to a BO, since the .dword field in the
555*61046927SAndroid Build Coastguard Worker * register's struct is only 32-bit wide. We should fix this in the pack
556*61046927SAndroid Build Coastguard Worker * codegen later.
557*61046927SAndroid Build Coastguard Worker */
558*61046927SAndroid Build Coastguard Worker #define tu_cs_emit_regs(cs, ...) do { \
559*61046927SAndroid Build Coastguard Worker const struct fd_reg_pair regs[] = { __VA_ARGS__ }; \
560*61046927SAndroid Build Coastguard Worker unsigned count = ARRAY_SIZE(regs); \
561*61046927SAndroid Build Coastguard Worker \
562*61046927SAndroid Build Coastguard Worker STATIC_ASSERT(ARRAY_SIZE(regs) > 0); \
563*61046927SAndroid Build Coastguard Worker STATIC_ASSERT(ARRAY_SIZE(regs) <= 16); \
564*61046927SAndroid Build Coastguard Worker \
565*61046927SAndroid Build Coastguard Worker tu_cs_emit_pkt4((cs), regs[0].reg, count); \
566*61046927SAndroid Build Coastguard Worker uint32_t *p = (cs)->cur; \
567*61046927SAndroid Build Coastguard Worker __ONE_REG( 0, regs); \
568*61046927SAndroid Build Coastguard Worker __ONE_REG( 1, regs); \
569*61046927SAndroid Build Coastguard Worker __ONE_REG( 2, regs); \
570*61046927SAndroid Build Coastguard Worker __ONE_REG( 3, regs); \
571*61046927SAndroid Build Coastguard Worker __ONE_REG( 4, regs); \
572*61046927SAndroid Build Coastguard Worker __ONE_REG( 5, regs); \
573*61046927SAndroid Build Coastguard Worker __ONE_REG( 6, regs); \
574*61046927SAndroid Build Coastguard Worker __ONE_REG( 7, regs); \
575*61046927SAndroid Build Coastguard Worker __ONE_REG( 8, regs); \
576*61046927SAndroid Build Coastguard Worker __ONE_REG( 9, regs); \
577*61046927SAndroid Build Coastguard Worker __ONE_REG(10, regs); \
578*61046927SAndroid Build Coastguard Worker __ONE_REG(11, regs); \
579*61046927SAndroid Build Coastguard Worker __ONE_REG(12, regs); \
580*61046927SAndroid Build Coastguard Worker __ONE_REG(13, regs); \
581*61046927SAndroid Build Coastguard Worker __ONE_REG(14, regs); \
582*61046927SAndroid Build Coastguard Worker __ONE_REG(15, regs); \
583*61046927SAndroid Build Coastguard Worker (cs)->cur = p; \
584*61046927SAndroid Build Coastguard Worker } while (0)
585*61046927SAndroid Build Coastguard Worker
586*61046927SAndroid Build Coastguard Worker #endif /* TU_CS_H */
587