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 #include "tu_cs.h"
7*61046927SAndroid Build Coastguard Worker
8*61046927SAndroid Build Coastguard Worker #include "tu_device.h"
9*61046927SAndroid Build Coastguard Worker #include "tu_rmv.h"
10*61046927SAndroid Build Coastguard Worker #include "tu_suballoc.h"
11*61046927SAndroid Build Coastguard Worker
12*61046927SAndroid Build Coastguard Worker /**
13*61046927SAndroid Build Coastguard Worker * Initialize a command stream.
14*61046927SAndroid Build Coastguard Worker */
15*61046927SAndroid Build Coastguard Worker void
tu_cs_init(struct tu_cs * cs,struct tu_device * device,enum tu_cs_mode mode,uint32_t initial_size,const char * name)16*61046927SAndroid Build Coastguard Worker tu_cs_init(struct tu_cs *cs,
17*61046927SAndroid Build Coastguard Worker struct tu_device *device,
18*61046927SAndroid Build Coastguard Worker enum tu_cs_mode mode,
19*61046927SAndroid Build Coastguard Worker uint32_t initial_size, const char *name)
20*61046927SAndroid Build Coastguard Worker {
21*61046927SAndroid Build Coastguard Worker assert(mode != TU_CS_MODE_EXTERNAL);
22*61046927SAndroid Build Coastguard Worker
23*61046927SAndroid Build Coastguard Worker memset(cs, 0, sizeof(*cs));
24*61046927SAndroid Build Coastguard Worker
25*61046927SAndroid Build Coastguard Worker cs->device = device;
26*61046927SAndroid Build Coastguard Worker cs->mode = mode;
27*61046927SAndroid Build Coastguard Worker cs->next_bo_size = initial_size;
28*61046927SAndroid Build Coastguard Worker cs->name = name;
29*61046927SAndroid Build Coastguard Worker }
30*61046927SAndroid Build Coastguard Worker
31*61046927SAndroid Build Coastguard Worker /**
32*61046927SAndroid Build Coastguard Worker * Initialize a command stream as a wrapper to an external buffer.
33*61046927SAndroid Build Coastguard Worker */
34*61046927SAndroid Build Coastguard Worker void
tu_cs_init_external(struct tu_cs * cs,struct tu_device * device,uint32_t * start,uint32_t * end,uint64_t iova,bool writeable)35*61046927SAndroid Build Coastguard Worker tu_cs_init_external(struct tu_cs *cs, struct tu_device *device,
36*61046927SAndroid Build Coastguard Worker uint32_t *start, uint32_t *end, uint64_t iova,
37*61046927SAndroid Build Coastguard Worker bool writeable)
38*61046927SAndroid Build Coastguard Worker {
39*61046927SAndroid Build Coastguard Worker memset(cs, 0, sizeof(*cs));
40*61046927SAndroid Build Coastguard Worker
41*61046927SAndroid Build Coastguard Worker cs->device = device;
42*61046927SAndroid Build Coastguard Worker cs->mode = TU_CS_MODE_EXTERNAL;
43*61046927SAndroid Build Coastguard Worker cs->start = cs->reserved_end = cs->cur = start;
44*61046927SAndroid Build Coastguard Worker cs->end = end;
45*61046927SAndroid Build Coastguard Worker cs->external_iova = iova;
46*61046927SAndroid Build Coastguard Worker cs->writeable = writeable;
47*61046927SAndroid Build Coastguard Worker }
48*61046927SAndroid Build Coastguard Worker
49*61046927SAndroid Build Coastguard Worker /**
50*61046927SAndroid Build Coastguard Worker * Initialize a sub-command stream as a wrapper to an externally sub-allocated
51*61046927SAndroid Build Coastguard Worker * buffer.
52*61046927SAndroid Build Coastguard Worker */
53*61046927SAndroid Build Coastguard Worker void
tu_cs_init_suballoc(struct tu_cs * cs,struct tu_device * device,struct tu_suballoc_bo * suballoc_bo)54*61046927SAndroid Build Coastguard Worker tu_cs_init_suballoc(struct tu_cs *cs, struct tu_device *device,
55*61046927SAndroid Build Coastguard Worker struct tu_suballoc_bo *suballoc_bo)
56*61046927SAndroid Build Coastguard Worker {
57*61046927SAndroid Build Coastguard Worker uint32_t *start = (uint32_t *) tu_suballoc_bo_map(suballoc_bo);
58*61046927SAndroid Build Coastguard Worker uint32_t *end = start + (suballoc_bo->size >> 2);
59*61046927SAndroid Build Coastguard Worker
60*61046927SAndroid Build Coastguard Worker memset(cs, 0, sizeof(*cs));
61*61046927SAndroid Build Coastguard Worker cs->device = device;
62*61046927SAndroid Build Coastguard Worker cs->mode = TU_CS_MODE_SUB_STREAM;
63*61046927SAndroid Build Coastguard Worker cs->start = cs->reserved_end = cs->cur = start;
64*61046927SAndroid Build Coastguard Worker cs->end = end;
65*61046927SAndroid Build Coastguard Worker cs->refcount_bo = tu_bo_get_ref(suballoc_bo->bo);
66*61046927SAndroid Build Coastguard Worker }
67*61046927SAndroid Build Coastguard Worker
68*61046927SAndroid Build Coastguard Worker /**
69*61046927SAndroid Build Coastguard Worker * Finish and release all resources owned by a command stream.
70*61046927SAndroid Build Coastguard Worker */
71*61046927SAndroid Build Coastguard Worker void
tu_cs_finish(struct tu_cs * cs)72*61046927SAndroid Build Coastguard Worker tu_cs_finish(struct tu_cs *cs)
73*61046927SAndroid Build Coastguard Worker {
74*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < cs->read_only.bo_count; ++i) {
75*61046927SAndroid Build Coastguard Worker TU_RMV(resource_destroy, cs->device, cs->read_only.bos[i]);
76*61046927SAndroid Build Coastguard Worker tu_bo_finish(cs->device, cs->read_only.bos[i]);
77*61046927SAndroid Build Coastguard Worker }
78*61046927SAndroid Build Coastguard Worker
79*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < cs->read_write.bo_count; ++i) {
80*61046927SAndroid Build Coastguard Worker TU_RMV(resource_destroy, cs->device, cs->read_write.bos[i]);
81*61046927SAndroid Build Coastguard Worker tu_bo_finish(cs->device, cs->read_write.bos[i]);
82*61046927SAndroid Build Coastguard Worker }
83*61046927SAndroid Build Coastguard Worker
84*61046927SAndroid Build Coastguard Worker if (cs->refcount_bo)
85*61046927SAndroid Build Coastguard Worker tu_bo_finish(cs->device, cs->refcount_bo);
86*61046927SAndroid Build Coastguard Worker
87*61046927SAndroid Build Coastguard Worker free(cs->entries);
88*61046927SAndroid Build Coastguard Worker free(cs->read_only.bos);
89*61046927SAndroid Build Coastguard Worker free(cs->read_write.bos);
90*61046927SAndroid Build Coastguard Worker }
91*61046927SAndroid Build Coastguard Worker
92*61046927SAndroid Build Coastguard Worker static struct tu_bo *
tu_cs_current_bo(const struct tu_cs * cs)93*61046927SAndroid Build Coastguard Worker tu_cs_current_bo(const struct tu_cs *cs)
94*61046927SAndroid Build Coastguard Worker {
95*61046927SAndroid Build Coastguard Worker if (cs->refcount_bo) {
96*61046927SAndroid Build Coastguard Worker return cs->refcount_bo;
97*61046927SAndroid Build Coastguard Worker } else {
98*61046927SAndroid Build Coastguard Worker const struct tu_bo_array *bos = cs->writeable ? &cs->read_write : &cs->read_only;
99*61046927SAndroid Build Coastguard Worker assert(bos->bo_count);
100*61046927SAndroid Build Coastguard Worker return bos->bos[bos->bo_count - 1];
101*61046927SAndroid Build Coastguard Worker }
102*61046927SAndroid Build Coastguard Worker }
103*61046927SAndroid Build Coastguard Worker
104*61046927SAndroid Build Coastguard Worker /**
105*61046927SAndroid Build Coastguard Worker * Get the offset of the command packets emitted since the last call to
106*61046927SAndroid Build Coastguard Worker * tu_cs_add_entry.
107*61046927SAndroid Build Coastguard Worker */
108*61046927SAndroid Build Coastguard Worker static uint32_t
tu_cs_get_offset(const struct tu_cs * cs)109*61046927SAndroid Build Coastguard Worker tu_cs_get_offset(const struct tu_cs *cs)
110*61046927SAndroid Build Coastguard Worker {
111*61046927SAndroid Build Coastguard Worker const struct tu_bo_array *bos = cs->writeable ? &cs->read_write : &cs->read_only;
112*61046927SAndroid Build Coastguard Worker return (cs->refcount_bo || bos->bo_count != 0) ? cs->start - (uint32_t *) tu_cs_current_bo(cs)->map : 0;
113*61046927SAndroid Build Coastguard Worker }
114*61046927SAndroid Build Coastguard Worker
115*61046927SAndroid Build Coastguard Worker /* Get the iova for the next dword to be emitted. Useful after
116*61046927SAndroid Build Coastguard Worker * tu_cs_reserve_space() to create a patch point that can be overwritten on
117*61046927SAndroid Build Coastguard Worker * the GPU.
118*61046927SAndroid Build Coastguard Worker */
119*61046927SAndroid Build Coastguard Worker uint64_t
tu_cs_get_cur_iova(const struct tu_cs * cs)120*61046927SAndroid Build Coastguard Worker tu_cs_get_cur_iova(const struct tu_cs *cs)
121*61046927SAndroid Build Coastguard Worker {
122*61046927SAndroid Build Coastguard Worker if (cs->mode == TU_CS_MODE_EXTERNAL)
123*61046927SAndroid Build Coastguard Worker return cs->external_iova + ((char *) cs->cur - (char *) cs->start);
124*61046927SAndroid Build Coastguard Worker return tu_cs_current_bo(cs)->iova + ((char *) cs->cur - (char *) tu_cs_current_bo(cs)->map);
125*61046927SAndroid Build Coastguard Worker }
126*61046927SAndroid Build Coastguard Worker
127*61046927SAndroid Build Coastguard Worker /*
128*61046927SAndroid Build Coastguard Worker * Allocate and add a BO to a command stream. Following command packets will
129*61046927SAndroid Build Coastguard Worker * be emitted to the new BO.
130*61046927SAndroid Build Coastguard Worker */
131*61046927SAndroid Build Coastguard Worker static VkResult
tu_cs_add_bo(struct tu_cs * cs,uint32_t size)132*61046927SAndroid Build Coastguard Worker tu_cs_add_bo(struct tu_cs *cs, uint32_t size)
133*61046927SAndroid Build Coastguard Worker {
134*61046927SAndroid Build Coastguard Worker /* no BO for TU_CS_MODE_EXTERNAL */
135*61046927SAndroid Build Coastguard Worker assert(cs->mode != TU_CS_MODE_EXTERNAL);
136*61046927SAndroid Build Coastguard Worker /* No adding more BOs if suballocating from a suballoc_bo. */
137*61046927SAndroid Build Coastguard Worker assert(!cs->refcount_bo);
138*61046927SAndroid Build Coastguard Worker
139*61046927SAndroid Build Coastguard Worker /* no dangling command packet */
140*61046927SAndroid Build Coastguard Worker assert(tu_cs_is_empty(cs));
141*61046927SAndroid Build Coastguard Worker
142*61046927SAndroid Build Coastguard Worker struct tu_bo_array *bos = cs->writeable ? &cs->read_write : &cs->read_only;
143*61046927SAndroid Build Coastguard Worker
144*61046927SAndroid Build Coastguard Worker /* grow cs->bos if needed */
145*61046927SAndroid Build Coastguard Worker if (bos->bo_count == bos->bo_capacity) {
146*61046927SAndroid Build Coastguard Worker uint32_t new_capacity = MAX2(4, 2 * bos->bo_capacity);
147*61046927SAndroid Build Coastguard Worker struct tu_bo **new_bos = (struct tu_bo **)
148*61046927SAndroid Build Coastguard Worker realloc(bos->bos, new_capacity * sizeof(struct tu_bo *));
149*61046927SAndroid Build Coastguard Worker if (!new_bos)
150*61046927SAndroid Build Coastguard Worker return VK_ERROR_OUT_OF_HOST_MEMORY;
151*61046927SAndroid Build Coastguard Worker
152*61046927SAndroid Build Coastguard Worker bos->bo_capacity = new_capacity;
153*61046927SAndroid Build Coastguard Worker bos->bos = new_bos;
154*61046927SAndroid Build Coastguard Worker }
155*61046927SAndroid Build Coastguard Worker
156*61046927SAndroid Build Coastguard Worker struct tu_bo *new_bo;
157*61046927SAndroid Build Coastguard Worker
158*61046927SAndroid Build Coastguard Worker VkResult result =
159*61046927SAndroid Build Coastguard Worker tu_bo_init_new(cs->device, NULL, &new_bo, size * sizeof(uint32_t),
160*61046927SAndroid Build Coastguard Worker (enum tu_bo_alloc_flags)(COND(!cs->writeable,
161*61046927SAndroid Build Coastguard Worker TU_BO_ALLOC_GPU_READ_ONLY) |
162*61046927SAndroid Build Coastguard Worker TU_BO_ALLOC_ALLOW_DUMP),
163*61046927SAndroid Build Coastguard Worker cs->name);
164*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS) {
165*61046927SAndroid Build Coastguard Worker return result;
166*61046927SAndroid Build Coastguard Worker }
167*61046927SAndroid Build Coastguard Worker
168*61046927SAndroid Build Coastguard Worker result = tu_bo_map(cs->device, new_bo, NULL);
169*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS) {
170*61046927SAndroid Build Coastguard Worker tu_bo_finish(cs->device, new_bo);
171*61046927SAndroid Build Coastguard Worker return result;
172*61046927SAndroid Build Coastguard Worker }
173*61046927SAndroid Build Coastguard Worker
174*61046927SAndroid Build Coastguard Worker TU_RMV(cmd_buffer_bo_create, cs->device, new_bo);
175*61046927SAndroid Build Coastguard Worker
176*61046927SAndroid Build Coastguard Worker bos->bos[bos->bo_count++] = new_bo;
177*61046927SAndroid Build Coastguard Worker
178*61046927SAndroid Build Coastguard Worker cs->start = cs->cur = cs->reserved_end = (uint32_t *) new_bo->map;
179*61046927SAndroid Build Coastguard Worker cs->end = cs->start + new_bo->size / sizeof(uint32_t);
180*61046927SAndroid Build Coastguard Worker
181*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
182*61046927SAndroid Build Coastguard Worker }
183*61046927SAndroid Build Coastguard Worker
184*61046927SAndroid Build Coastguard Worker /**
185*61046927SAndroid Build Coastguard Worker * Reserve an IB entry.
186*61046927SAndroid Build Coastguard Worker */
187*61046927SAndroid Build Coastguard Worker static VkResult
tu_cs_reserve_entry(struct tu_cs * cs)188*61046927SAndroid Build Coastguard Worker tu_cs_reserve_entry(struct tu_cs *cs)
189*61046927SAndroid Build Coastguard Worker {
190*61046927SAndroid Build Coastguard Worker /* entries are only for TU_CS_MODE_GROW */
191*61046927SAndroid Build Coastguard Worker assert(cs->mode == TU_CS_MODE_GROW);
192*61046927SAndroid Build Coastguard Worker
193*61046927SAndroid Build Coastguard Worker /* grow cs->entries if needed */
194*61046927SAndroid Build Coastguard Worker if (cs->entry_count == cs->entry_capacity) {
195*61046927SAndroid Build Coastguard Worker uint32_t new_capacity = MAX2(4, cs->entry_capacity * 2);
196*61046927SAndroid Build Coastguard Worker struct tu_cs_entry *new_entries = (struct tu_cs_entry *)
197*61046927SAndroid Build Coastguard Worker realloc(cs->entries, new_capacity * sizeof(struct tu_cs_entry));
198*61046927SAndroid Build Coastguard Worker if (!new_entries)
199*61046927SAndroid Build Coastguard Worker return VK_ERROR_OUT_OF_HOST_MEMORY;
200*61046927SAndroid Build Coastguard Worker
201*61046927SAndroid Build Coastguard Worker cs->entry_capacity = new_capacity;
202*61046927SAndroid Build Coastguard Worker cs->entries = new_entries;
203*61046927SAndroid Build Coastguard Worker }
204*61046927SAndroid Build Coastguard Worker
205*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
206*61046927SAndroid Build Coastguard Worker }
207*61046927SAndroid Build Coastguard Worker
208*61046927SAndroid Build Coastguard Worker
209*61046927SAndroid Build Coastguard Worker /**
210*61046927SAndroid Build Coastguard Worker * Add an IB entry for the command packets emitted since the last call to this
211*61046927SAndroid Build Coastguard Worker * function.
212*61046927SAndroid Build Coastguard Worker */
213*61046927SAndroid Build Coastguard Worker static void
tu_cs_add_entry(struct tu_cs * cs)214*61046927SAndroid Build Coastguard Worker tu_cs_add_entry(struct tu_cs *cs)
215*61046927SAndroid Build Coastguard Worker {
216*61046927SAndroid Build Coastguard Worker /* entries are only for TU_CS_MODE_GROW */
217*61046927SAndroid Build Coastguard Worker assert(cs->mode == TU_CS_MODE_GROW);
218*61046927SAndroid Build Coastguard Worker
219*61046927SAndroid Build Coastguard Worker /* disallow empty entry */
220*61046927SAndroid Build Coastguard Worker assert(!tu_cs_is_empty(cs));
221*61046927SAndroid Build Coastguard Worker
222*61046927SAndroid Build Coastguard Worker /*
223*61046927SAndroid Build Coastguard Worker * because we disallow empty entry, tu_cs_add_bo and tu_cs_reserve_entry
224*61046927SAndroid Build Coastguard Worker * must both have been called
225*61046927SAndroid Build Coastguard Worker */
226*61046927SAndroid Build Coastguard Worker assert(cs->writeable ? cs->read_write.bo_count : cs->read_only.bo_count);
227*61046927SAndroid Build Coastguard Worker assert(cs->entry_count < cs->entry_capacity);
228*61046927SAndroid Build Coastguard Worker
229*61046927SAndroid Build Coastguard Worker /* add an entry for [cs->start, cs->cur] */
230*61046927SAndroid Build Coastguard Worker cs->entries[cs->entry_count++] = (struct tu_cs_entry) {
231*61046927SAndroid Build Coastguard Worker .bo = tu_cs_current_bo(cs),
232*61046927SAndroid Build Coastguard Worker .size = tu_cs_get_size(cs) * sizeof(uint32_t),
233*61046927SAndroid Build Coastguard Worker .offset = tu_cs_get_offset(cs) * sizeof(uint32_t),
234*61046927SAndroid Build Coastguard Worker };
235*61046927SAndroid Build Coastguard Worker
236*61046927SAndroid Build Coastguard Worker cs->start = cs->cur;
237*61046927SAndroid Build Coastguard Worker }
238*61046927SAndroid Build Coastguard Worker
239*61046927SAndroid Build Coastguard Worker /**
240*61046927SAndroid Build Coastguard Worker * same behavior as tu_cs_emit_call but without the indirect
241*61046927SAndroid Build Coastguard Worker */
242*61046927SAndroid Build Coastguard Worker VkResult
tu_cs_add_entries(struct tu_cs * cs,struct tu_cs * target)243*61046927SAndroid Build Coastguard Worker tu_cs_add_entries(struct tu_cs *cs, struct tu_cs *target)
244*61046927SAndroid Build Coastguard Worker {
245*61046927SAndroid Build Coastguard Worker VkResult result;
246*61046927SAndroid Build Coastguard Worker
247*61046927SAndroid Build Coastguard Worker assert(cs->mode == TU_CS_MODE_GROW);
248*61046927SAndroid Build Coastguard Worker assert(target->mode == TU_CS_MODE_GROW);
249*61046927SAndroid Build Coastguard Worker
250*61046927SAndroid Build Coastguard Worker if (!tu_cs_is_empty(cs))
251*61046927SAndroid Build Coastguard Worker tu_cs_add_entry(cs);
252*61046927SAndroid Build Coastguard Worker
253*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < target->entry_count; i++) {
254*61046927SAndroid Build Coastguard Worker result = tu_cs_reserve_entry(cs);
255*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
256*61046927SAndroid Build Coastguard Worker return result;
257*61046927SAndroid Build Coastguard Worker cs->entries[cs->entry_count++] = target->entries[i];
258*61046927SAndroid Build Coastguard Worker }
259*61046927SAndroid Build Coastguard Worker
260*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
261*61046927SAndroid Build Coastguard Worker }
262*61046927SAndroid Build Coastguard Worker
263*61046927SAndroid Build Coastguard Worker /**
264*61046927SAndroid Build Coastguard Worker * Begin (or continue) command packet emission. This does nothing but sanity
265*61046927SAndroid Build Coastguard Worker * checks currently. \a cs must not be in TU_CS_MODE_SUB_STREAM mode.
266*61046927SAndroid Build Coastguard Worker */
267*61046927SAndroid Build Coastguard Worker void
tu_cs_begin(struct tu_cs * cs)268*61046927SAndroid Build Coastguard Worker tu_cs_begin(struct tu_cs *cs)
269*61046927SAndroid Build Coastguard Worker {
270*61046927SAndroid Build Coastguard Worker assert(cs->mode != TU_CS_MODE_SUB_STREAM);
271*61046927SAndroid Build Coastguard Worker assert(tu_cs_is_empty(cs));
272*61046927SAndroid Build Coastguard Worker }
273*61046927SAndroid Build Coastguard Worker
274*61046927SAndroid Build Coastguard Worker /**
275*61046927SAndroid Build Coastguard Worker * End command packet emission. This adds an IB entry when \a cs is in
276*61046927SAndroid Build Coastguard Worker * TU_CS_MODE_GROW mode.
277*61046927SAndroid Build Coastguard Worker */
278*61046927SAndroid Build Coastguard Worker void
tu_cs_end(struct tu_cs * cs)279*61046927SAndroid Build Coastguard Worker tu_cs_end(struct tu_cs *cs)
280*61046927SAndroid Build Coastguard Worker {
281*61046927SAndroid Build Coastguard Worker assert(cs->mode != TU_CS_MODE_SUB_STREAM);
282*61046927SAndroid Build Coastguard Worker
283*61046927SAndroid Build Coastguard Worker if (cs->mode == TU_CS_MODE_GROW && !tu_cs_is_empty(cs))
284*61046927SAndroid Build Coastguard Worker tu_cs_add_entry(cs);
285*61046927SAndroid Build Coastguard Worker }
286*61046927SAndroid Build Coastguard Worker
287*61046927SAndroid Build Coastguard Worker void
tu_cs_set_writeable(struct tu_cs * cs,bool writeable)288*61046927SAndroid Build Coastguard Worker tu_cs_set_writeable(struct tu_cs *cs, bool writeable)
289*61046927SAndroid Build Coastguard Worker {
290*61046927SAndroid Build Coastguard Worker assert(cs->mode == TU_CS_MODE_GROW || cs->mode == TU_CS_MODE_SUB_STREAM);
291*61046927SAndroid Build Coastguard Worker
292*61046927SAndroid Build Coastguard Worker if (cs->writeable != writeable) {
293*61046927SAndroid Build Coastguard Worker if (cs->mode == TU_CS_MODE_GROW && !tu_cs_is_empty(cs))
294*61046927SAndroid Build Coastguard Worker tu_cs_add_entry(cs);
295*61046927SAndroid Build Coastguard Worker struct tu_bo_array *old_bos = cs->writeable ? &cs->read_write : &cs->read_only;
296*61046927SAndroid Build Coastguard Worker struct tu_bo_array *new_bos = writeable ? &cs->read_write : &cs->read_only;
297*61046927SAndroid Build Coastguard Worker
298*61046927SAndroid Build Coastguard Worker old_bos->start = cs->start;
299*61046927SAndroid Build Coastguard Worker cs->start = cs->cur = cs->reserved_end = new_bos->start;
300*61046927SAndroid Build Coastguard Worker if (new_bos->bo_count) {
301*61046927SAndroid Build Coastguard Worker struct tu_bo *bo = new_bos->bos[new_bos->bo_count - 1];
302*61046927SAndroid Build Coastguard Worker cs->end = (uint32_t *)bo->map + bo->size / sizeof(uint32_t);
303*61046927SAndroid Build Coastguard Worker } else {
304*61046927SAndroid Build Coastguard Worker cs->end = NULL;
305*61046927SAndroid Build Coastguard Worker }
306*61046927SAndroid Build Coastguard Worker
307*61046927SAndroid Build Coastguard Worker cs->writeable = writeable;
308*61046927SAndroid Build Coastguard Worker }
309*61046927SAndroid Build Coastguard Worker }
310*61046927SAndroid Build Coastguard Worker
311*61046927SAndroid Build Coastguard Worker /**
312*61046927SAndroid Build Coastguard Worker * Begin command packet emission to a sub-stream. \a cs must be in
313*61046927SAndroid Build Coastguard Worker * TU_CS_MODE_SUB_STREAM mode.
314*61046927SAndroid Build Coastguard Worker *
315*61046927SAndroid Build Coastguard Worker * Return \a sub_cs which is in TU_CS_MODE_EXTERNAL mode. tu_cs_begin and
316*61046927SAndroid Build Coastguard Worker * tu_cs_reserve_space are implied and \a sub_cs is ready for command packet
317*61046927SAndroid Build Coastguard Worker * emission.
318*61046927SAndroid Build Coastguard Worker */
319*61046927SAndroid Build Coastguard Worker VkResult
tu_cs_begin_sub_stream_aligned(struct tu_cs * cs,uint32_t count,uint32_t size,struct tu_cs * sub_cs)320*61046927SAndroid Build Coastguard Worker tu_cs_begin_sub_stream_aligned(struct tu_cs *cs, uint32_t count,
321*61046927SAndroid Build Coastguard Worker uint32_t size, struct tu_cs *sub_cs)
322*61046927SAndroid Build Coastguard Worker {
323*61046927SAndroid Build Coastguard Worker assert(cs->mode == TU_CS_MODE_SUB_STREAM);
324*61046927SAndroid Build Coastguard Worker assert(size);
325*61046927SAndroid Build Coastguard Worker
326*61046927SAndroid Build Coastguard Worker VkResult result;
327*61046927SAndroid Build Coastguard Worker if (tu_cs_get_space(cs) < count * size) {
328*61046927SAndroid Build Coastguard Worker /* When we have to allocate a new BO, assume that the alignment of the
329*61046927SAndroid Build Coastguard Worker * BO is sufficient.
330*61046927SAndroid Build Coastguard Worker */
331*61046927SAndroid Build Coastguard Worker result = tu_cs_reserve_space(cs, count * size);
332*61046927SAndroid Build Coastguard Worker } else {
333*61046927SAndroid Build Coastguard Worker result = tu_cs_reserve_space(cs, count * size + (size - tu_cs_get_offset(cs)) % size);
334*61046927SAndroid Build Coastguard Worker cs->start += (size - tu_cs_get_offset(cs)) % size;
335*61046927SAndroid Build Coastguard Worker }
336*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
337*61046927SAndroid Build Coastguard Worker return result;
338*61046927SAndroid Build Coastguard Worker
339*61046927SAndroid Build Coastguard Worker cs->cur = cs->start;
340*61046927SAndroid Build Coastguard Worker
341*61046927SAndroid Build Coastguard Worker tu_cs_init_external(sub_cs, cs->device, cs->cur, cs->reserved_end,
342*61046927SAndroid Build Coastguard Worker tu_cs_get_cur_iova(cs), cs->writeable);
343*61046927SAndroid Build Coastguard Worker tu_cs_begin(sub_cs);
344*61046927SAndroid Build Coastguard Worker result = tu_cs_reserve_space(sub_cs, count * size);
345*61046927SAndroid Build Coastguard Worker assert(result == VK_SUCCESS);
346*61046927SAndroid Build Coastguard Worker
347*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
348*61046927SAndroid Build Coastguard Worker }
349*61046927SAndroid Build Coastguard Worker
350*61046927SAndroid Build Coastguard Worker /**
351*61046927SAndroid Build Coastguard Worker * Allocate count*size dwords, aligned to size dwords.
352*61046927SAndroid Build Coastguard Worker * \a cs must be in TU_CS_MODE_SUB_STREAM mode.
353*61046927SAndroid Build Coastguard Worker *
354*61046927SAndroid Build Coastguard Worker */
355*61046927SAndroid Build Coastguard Worker VkResult
tu_cs_alloc(struct tu_cs * cs,uint32_t count,uint32_t size,struct tu_cs_memory * memory)356*61046927SAndroid Build Coastguard Worker tu_cs_alloc(struct tu_cs *cs,
357*61046927SAndroid Build Coastguard Worker uint32_t count,
358*61046927SAndroid Build Coastguard Worker uint32_t size,
359*61046927SAndroid Build Coastguard Worker struct tu_cs_memory *memory)
360*61046927SAndroid Build Coastguard Worker {
361*61046927SAndroid Build Coastguard Worker assert(cs->mode == TU_CS_MODE_SUB_STREAM);
362*61046927SAndroid Build Coastguard Worker assert(size && size <= 1024);
363*61046927SAndroid Build Coastguard Worker
364*61046927SAndroid Build Coastguard Worker if (!count) {
365*61046927SAndroid Build Coastguard Worker /* If you allocated no memory, you'd better not use the iova for anything
366*61046927SAndroid Build Coastguard Worker * (but it's left aligned for sanity).
367*61046927SAndroid Build Coastguard Worker */
368*61046927SAndroid Build Coastguard Worker memory->map = NULL;
369*61046927SAndroid Build Coastguard Worker memory->iova = 0xdead0000;
370*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
371*61046927SAndroid Build Coastguard Worker }
372*61046927SAndroid Build Coastguard Worker
373*61046927SAndroid Build Coastguard Worker /* TODO: smarter way to deal with alignment? */
374*61046927SAndroid Build Coastguard Worker
375*61046927SAndroid Build Coastguard Worker VkResult result = tu_cs_reserve_space(cs, count * size + (size-1));
376*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
377*61046927SAndroid Build Coastguard Worker return result;
378*61046927SAndroid Build Coastguard Worker
379*61046927SAndroid Build Coastguard Worker struct tu_bo *bo = tu_cs_current_bo(cs);
380*61046927SAndroid Build Coastguard Worker size_t offset = align(tu_cs_get_offset(cs), size);
381*61046927SAndroid Build Coastguard Worker
382*61046927SAndroid Build Coastguard Worker memory->map = (uint32_t *) bo->map + offset;
383*61046927SAndroid Build Coastguard Worker memory->iova = bo->iova + offset * sizeof(uint32_t);
384*61046927SAndroid Build Coastguard Worker memory->writeable = cs->writeable;
385*61046927SAndroid Build Coastguard Worker
386*61046927SAndroid Build Coastguard Worker cs->start = cs->cur = (uint32_t*) bo->map + offset + count * size;
387*61046927SAndroid Build Coastguard Worker
388*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
389*61046927SAndroid Build Coastguard Worker }
390*61046927SAndroid Build Coastguard Worker
391*61046927SAndroid Build Coastguard Worker /**
392*61046927SAndroid Build Coastguard Worker * End command packet emission to a sub-stream. \a sub_cs becomes invalid
393*61046927SAndroid Build Coastguard Worker * after this call.
394*61046927SAndroid Build Coastguard Worker *
395*61046927SAndroid Build Coastguard Worker * Return an IB entry for the sub-stream. The entry has the same lifetime as
396*61046927SAndroid Build Coastguard Worker * \a cs.
397*61046927SAndroid Build Coastguard Worker */
398*61046927SAndroid Build Coastguard Worker struct tu_cs_entry
tu_cs_end_sub_stream(struct tu_cs * cs,struct tu_cs * sub_cs)399*61046927SAndroid Build Coastguard Worker tu_cs_end_sub_stream(struct tu_cs *cs, struct tu_cs *sub_cs)
400*61046927SAndroid Build Coastguard Worker {
401*61046927SAndroid Build Coastguard Worker assert(cs->mode == TU_CS_MODE_SUB_STREAM);
402*61046927SAndroid Build Coastguard Worker assert(sub_cs->start == cs->cur && sub_cs->end == cs->reserved_end);
403*61046927SAndroid Build Coastguard Worker tu_cs_sanity_check(sub_cs);
404*61046927SAndroid Build Coastguard Worker
405*61046927SAndroid Build Coastguard Worker tu_cs_end(sub_cs);
406*61046927SAndroid Build Coastguard Worker
407*61046927SAndroid Build Coastguard Worker cs->cur = sub_cs->cur;
408*61046927SAndroid Build Coastguard Worker
409*61046927SAndroid Build Coastguard Worker struct tu_cs_entry entry = {
410*61046927SAndroid Build Coastguard Worker .bo = tu_cs_current_bo(cs),
411*61046927SAndroid Build Coastguard Worker .size = tu_cs_get_size(cs) * sizeof(uint32_t),
412*61046927SAndroid Build Coastguard Worker .offset = tu_cs_get_offset(cs) * sizeof(uint32_t),
413*61046927SAndroid Build Coastguard Worker };
414*61046927SAndroid Build Coastguard Worker
415*61046927SAndroid Build Coastguard Worker cs->start = cs->cur;
416*61046927SAndroid Build Coastguard Worker
417*61046927SAndroid Build Coastguard Worker return entry;
418*61046927SAndroid Build Coastguard Worker }
419*61046927SAndroid Build Coastguard Worker
420*61046927SAndroid Build Coastguard Worker /**
421*61046927SAndroid Build Coastguard Worker * Reserve space from a command stream for \a reserved_size uint32_t values.
422*61046927SAndroid Build Coastguard Worker * This never fails when \a cs has mode TU_CS_MODE_EXTERNAL.
423*61046927SAndroid Build Coastguard Worker */
424*61046927SAndroid Build Coastguard Worker VkResult
tu_cs_reserve_space(struct tu_cs * cs,uint32_t reserved_size)425*61046927SAndroid Build Coastguard Worker tu_cs_reserve_space(struct tu_cs *cs, uint32_t reserved_size)
426*61046927SAndroid Build Coastguard Worker {
427*61046927SAndroid Build Coastguard Worker if (tu_cs_get_space(cs) < reserved_size) {
428*61046927SAndroid Build Coastguard Worker if (cs->mode == TU_CS_MODE_EXTERNAL) {
429*61046927SAndroid Build Coastguard Worker unreachable("cannot grow external buffer");
430*61046927SAndroid Build Coastguard Worker return VK_ERROR_OUT_OF_HOST_MEMORY;
431*61046927SAndroid Build Coastguard Worker }
432*61046927SAndroid Build Coastguard Worker
433*61046927SAndroid Build Coastguard Worker /* add an entry for the exiting command packets */
434*61046927SAndroid Build Coastguard Worker if (!tu_cs_is_empty(cs)) {
435*61046927SAndroid Build Coastguard Worker /* no direct command packet for TU_CS_MODE_SUB_STREAM */
436*61046927SAndroid Build Coastguard Worker assert(cs->mode != TU_CS_MODE_SUB_STREAM);
437*61046927SAndroid Build Coastguard Worker
438*61046927SAndroid Build Coastguard Worker tu_cs_add_entry(cs);
439*61046927SAndroid Build Coastguard Worker }
440*61046927SAndroid Build Coastguard Worker
441*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < cs->cond_stack_depth; i++) {
442*61046927SAndroid Build Coastguard Worker /* Subtract one here to account for the DWORD field itself. */
443*61046927SAndroid Build Coastguard Worker *cs->cond_dwords[i] = cs->cur - cs->cond_dwords[i] - 1;
444*61046927SAndroid Build Coastguard Worker
445*61046927SAndroid Build Coastguard Worker /* space for CP_COND_REG_EXEC in next bo */
446*61046927SAndroid Build Coastguard Worker reserved_size += 3;
447*61046927SAndroid Build Coastguard Worker }
448*61046927SAndroid Build Coastguard Worker
449*61046927SAndroid Build Coastguard Worker /* switch to a new BO */
450*61046927SAndroid Build Coastguard Worker uint32_t new_size = MAX2(cs->next_bo_size, reserved_size);
451*61046927SAndroid Build Coastguard Worker VkResult result = tu_cs_add_bo(cs, new_size);
452*61046927SAndroid Build Coastguard Worker if (result != VK_SUCCESS)
453*61046927SAndroid Build Coastguard Worker return result;
454*61046927SAndroid Build Coastguard Worker
455*61046927SAndroid Build Coastguard Worker if (cs->cond_stack_depth) {
456*61046927SAndroid Build Coastguard Worker cs->reserved_end = cs->cur + reserved_size;
457*61046927SAndroid Build Coastguard Worker }
458*61046927SAndroid Build Coastguard Worker
459*61046927SAndroid Build Coastguard Worker /* Re-emit CP_COND_REG_EXECs */
460*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i < cs->cond_stack_depth; i++) {
461*61046927SAndroid Build Coastguard Worker tu_cs_emit_pkt7(cs, CP_COND_REG_EXEC, 2);
462*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, cs->cond_flags[i]);
463*61046927SAndroid Build Coastguard Worker
464*61046927SAndroid Build Coastguard Worker cs->cond_dwords[i] = cs->cur;
465*61046927SAndroid Build Coastguard Worker
466*61046927SAndroid Build Coastguard Worker /* Emit dummy DWORD field here */
467*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, RENDER_MODE_CP_COND_REG_EXEC_1_DWORDS(0));
468*61046927SAndroid Build Coastguard Worker }
469*61046927SAndroid Build Coastguard Worker
470*61046927SAndroid Build Coastguard Worker /* double the size for the next bo, also there is an upper
471*61046927SAndroid Build Coastguard Worker * bound on IB size, which appears to be 0x0fffff
472*61046927SAndroid Build Coastguard Worker */
473*61046927SAndroid Build Coastguard Worker new_size = MIN2(new_size << 1, 0x0fffff);
474*61046927SAndroid Build Coastguard Worker if (cs->next_bo_size < new_size)
475*61046927SAndroid Build Coastguard Worker cs->next_bo_size = new_size;
476*61046927SAndroid Build Coastguard Worker }
477*61046927SAndroid Build Coastguard Worker
478*61046927SAndroid Build Coastguard Worker assert(tu_cs_get_space(cs) >= reserved_size);
479*61046927SAndroid Build Coastguard Worker cs->reserved_end = cs->cur + reserved_size;
480*61046927SAndroid Build Coastguard Worker
481*61046927SAndroid Build Coastguard Worker if (cs->mode == TU_CS_MODE_GROW) {
482*61046927SAndroid Build Coastguard Worker /* reserve an entry for the next call to this function or tu_cs_end */
483*61046927SAndroid Build Coastguard Worker return tu_cs_reserve_entry(cs);
484*61046927SAndroid Build Coastguard Worker }
485*61046927SAndroid Build Coastguard Worker
486*61046927SAndroid Build Coastguard Worker return VK_SUCCESS;
487*61046927SAndroid Build Coastguard Worker }
488*61046927SAndroid Build Coastguard Worker
489*61046927SAndroid Build Coastguard Worker /**
490*61046927SAndroid Build Coastguard Worker * Reset a command stream to its initial state. This discards all comand
491*61046927SAndroid Build Coastguard Worker * packets in \a cs, but does not necessarily release all resources.
492*61046927SAndroid Build Coastguard Worker */
493*61046927SAndroid Build Coastguard Worker void
tu_cs_reset(struct tu_cs * cs)494*61046927SAndroid Build Coastguard Worker tu_cs_reset(struct tu_cs *cs)
495*61046927SAndroid Build Coastguard Worker {
496*61046927SAndroid Build Coastguard Worker if (cs->mode == TU_CS_MODE_EXTERNAL) {
497*61046927SAndroid Build Coastguard Worker assert(!cs->read_only.bo_count && !cs->read_write.bo_count &&
498*61046927SAndroid Build Coastguard Worker !cs->refcount_bo && !cs->entry_count);
499*61046927SAndroid Build Coastguard Worker cs->reserved_end = cs->cur = cs->start;
500*61046927SAndroid Build Coastguard Worker return;
501*61046927SAndroid Build Coastguard Worker }
502*61046927SAndroid Build Coastguard Worker
503*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i + 1 < cs->read_only.bo_count; ++i) {
504*61046927SAndroid Build Coastguard Worker TU_RMV(resource_destroy, cs->device, cs->read_only.bos[i]);
505*61046927SAndroid Build Coastguard Worker tu_bo_finish(cs->device, cs->read_only.bos[i]);
506*61046927SAndroid Build Coastguard Worker }
507*61046927SAndroid Build Coastguard Worker
508*61046927SAndroid Build Coastguard Worker for (uint32_t i = 0; i + 1 < cs->read_write.bo_count; ++i) {
509*61046927SAndroid Build Coastguard Worker TU_RMV(resource_destroy, cs->device, cs->read_write.bos[i]);
510*61046927SAndroid Build Coastguard Worker tu_bo_finish(cs->device, cs->read_write.bos[i]);
511*61046927SAndroid Build Coastguard Worker }
512*61046927SAndroid Build Coastguard Worker
513*61046927SAndroid Build Coastguard Worker cs->writeable = false;
514*61046927SAndroid Build Coastguard Worker
515*61046927SAndroid Build Coastguard Worker if (cs->read_only.bo_count) {
516*61046927SAndroid Build Coastguard Worker cs->read_only.bos[0] = cs->read_only.bos[cs->read_only.bo_count - 1];
517*61046927SAndroid Build Coastguard Worker cs->read_only.bo_count = 1;
518*61046927SAndroid Build Coastguard Worker
519*61046927SAndroid Build Coastguard Worker cs->start = cs->cur = cs->reserved_end = (uint32_t *) cs->read_only.bos[0]->map;
520*61046927SAndroid Build Coastguard Worker cs->end = cs->start + cs->read_only.bos[0]->size / sizeof(uint32_t);
521*61046927SAndroid Build Coastguard Worker }
522*61046927SAndroid Build Coastguard Worker
523*61046927SAndroid Build Coastguard Worker if (cs->read_write.bo_count) {
524*61046927SAndroid Build Coastguard Worker cs->read_write.bos[0] = cs->read_write.bos[cs->read_write.bo_count - 1];
525*61046927SAndroid Build Coastguard Worker cs->read_write.bo_count = 1;
526*61046927SAndroid Build Coastguard Worker }
527*61046927SAndroid Build Coastguard Worker
528*61046927SAndroid Build Coastguard Worker cs->entry_count = 0;
529*61046927SAndroid Build Coastguard Worker }
530*61046927SAndroid Build Coastguard Worker
531*61046927SAndroid Build Coastguard Worker uint64_t
tu_cs_emit_data_nop(struct tu_cs * cs,const uint32_t * data,uint32_t size,uint32_t align_dwords)532*61046927SAndroid Build Coastguard Worker tu_cs_emit_data_nop(struct tu_cs *cs,
533*61046927SAndroid Build Coastguard Worker const uint32_t *data,
534*61046927SAndroid Build Coastguard Worker uint32_t size,
535*61046927SAndroid Build Coastguard Worker uint32_t align_dwords)
536*61046927SAndroid Build Coastguard Worker {
537*61046927SAndroid Build Coastguard Worker uint32_t total_size = size + (align_dwords - 1);
538*61046927SAndroid Build Coastguard Worker tu_cs_emit_pkt7(cs, CP_NOP, total_size);
539*61046927SAndroid Build Coastguard Worker
540*61046927SAndroid Build Coastguard Worker uint64_t iova = tu_cs_get_cur_iova(cs);
541*61046927SAndroid Build Coastguard Worker uint64_t iova_aligned = align64(iova, align_dwords * sizeof(uint32_t));
542*61046927SAndroid Build Coastguard Worker size_t offset = (iova_aligned - iova) / sizeof(uint32_t);
543*61046927SAndroid Build Coastguard Worker cs->cur += offset;
544*61046927SAndroid Build Coastguard Worker memcpy(cs->cur, data, size * sizeof(uint32_t));
545*61046927SAndroid Build Coastguard Worker
546*61046927SAndroid Build Coastguard Worker cs->cur += total_size - offset;
547*61046927SAndroid Build Coastguard Worker
548*61046927SAndroid Build Coastguard Worker return iova + offset * sizeof(uint32_t);
549*61046927SAndroid Build Coastguard Worker }
550*61046927SAndroid Build Coastguard Worker
551*61046927SAndroid Build Coastguard Worker void
tu_cs_emit_debug_string(struct tu_cs * cs,const char * string,int len)552*61046927SAndroid Build Coastguard Worker tu_cs_emit_debug_string(struct tu_cs *cs, const char *string, int len)
553*61046927SAndroid Build Coastguard Worker {
554*61046927SAndroid Build Coastguard Worker assert(cs->mode == TU_CS_MODE_GROW);
555*61046927SAndroid Build Coastguard Worker
556*61046927SAndroid Build Coastguard Worker /* max packet size is 0x3fff dwords */
557*61046927SAndroid Build Coastguard Worker len = MIN2(len, 0x3fff * 4);
558*61046927SAndroid Build Coastguard Worker
559*61046927SAndroid Build Coastguard Worker tu_cs_emit_pkt7(cs, CP_NOP, align(len, 4) / 4);
560*61046927SAndroid Build Coastguard Worker const uint32_t *buf = (const uint32_t *) string;
561*61046927SAndroid Build Coastguard Worker
562*61046927SAndroid Build Coastguard Worker tu_cs_emit_array(cs, buf, len / 4);
563*61046927SAndroid Build Coastguard Worker buf += len / 4;
564*61046927SAndroid Build Coastguard Worker len = len % 4;
565*61046927SAndroid Build Coastguard Worker
566*61046927SAndroid Build Coastguard Worker /* copy remainder bytes without reading past end of input string */
567*61046927SAndroid Build Coastguard Worker if (len > 0) {
568*61046927SAndroid Build Coastguard Worker uint32_t w = 0;
569*61046927SAndroid Build Coastguard Worker memcpy(&w, buf, len);
570*61046927SAndroid Build Coastguard Worker tu_cs_emit(cs, w);
571*61046927SAndroid Build Coastguard Worker }
572*61046927SAndroid Build Coastguard Worker }
573*61046927SAndroid Build Coastguard Worker
574*61046927SAndroid Build Coastguard Worker void
tu_cs_emit_debug_magic_strv(struct tu_cs * cs,uint32_t magic,const char * fmt,va_list args)575*61046927SAndroid Build Coastguard Worker tu_cs_emit_debug_magic_strv(struct tu_cs *cs,
576*61046927SAndroid Build Coastguard Worker uint32_t magic,
577*61046927SAndroid Build Coastguard Worker const char *fmt,
578*61046927SAndroid Build Coastguard Worker va_list args)
579*61046927SAndroid Build Coastguard Worker {
580*61046927SAndroid Build Coastguard Worker int fmt_len = vsnprintf(NULL, 0, fmt, args);
581*61046927SAndroid Build Coastguard Worker int len = 4 + fmt_len + 1;
582*61046927SAndroid Build Coastguard Worker char *string = (char *) malloc(len);
583*61046927SAndroid Build Coastguard Worker
584*61046927SAndroid Build Coastguard Worker /* format: <magic><formatted string>\0 */
585*61046927SAndroid Build Coastguard Worker *(uint32_t *) string = magic;
586*61046927SAndroid Build Coastguard Worker vsnprintf(string + 4, fmt_len + 1, fmt, args);
587*61046927SAndroid Build Coastguard Worker
588*61046927SAndroid Build Coastguard Worker tu_cs_emit_debug_string(cs, string, len);
589*61046927SAndroid Build Coastguard Worker free(string);
590*61046927SAndroid Build Coastguard Worker }
591*61046927SAndroid Build Coastguard Worker
592*61046927SAndroid Build Coastguard Worker __attribute__((format(printf, 2, 3))) void
tu_cs_emit_debug_msg(struct tu_cs * cs,const char * fmt,...)593*61046927SAndroid Build Coastguard Worker tu_cs_emit_debug_msg(struct tu_cs *cs, const char *fmt, ...)
594*61046927SAndroid Build Coastguard Worker {
595*61046927SAndroid Build Coastguard Worker va_list args;
596*61046927SAndroid Build Coastguard Worker va_start(args, fmt);
597*61046927SAndroid Build Coastguard Worker tu_cs_emit_debug_magic_strv(cs, CP_NOP_MESG, fmt, args);
598*61046927SAndroid Build Coastguard Worker va_end(args);
599*61046927SAndroid Build Coastguard Worker }
600*61046927SAndroid Build Coastguard Worker
601*61046927SAndroid Build Coastguard Worker void
tu_cs_trace_start(struct u_trace_context * utctx,void * cs,const char * fmt,...)602*61046927SAndroid Build Coastguard Worker tu_cs_trace_start(struct u_trace_context *utctx,
603*61046927SAndroid Build Coastguard Worker void *cs,
604*61046927SAndroid Build Coastguard Worker const char *fmt,
605*61046927SAndroid Build Coastguard Worker ...)
606*61046927SAndroid Build Coastguard Worker {
607*61046927SAndroid Build Coastguard Worker va_list args;
608*61046927SAndroid Build Coastguard Worker va_start(args, fmt);
609*61046927SAndroid Build Coastguard Worker tu_cs_emit_debug_magic_strv((struct tu_cs *) cs, CP_NOP_BEGN, fmt, args);
610*61046927SAndroid Build Coastguard Worker va_end(args);
611*61046927SAndroid Build Coastguard Worker }
612*61046927SAndroid Build Coastguard Worker
613*61046927SAndroid Build Coastguard Worker void
tu_cs_trace_end(struct u_trace_context * utctx,void * cs,const char * fmt,...)614*61046927SAndroid Build Coastguard Worker tu_cs_trace_end(struct u_trace_context *utctx, void *cs, const char *fmt, ...)
615*61046927SAndroid Build Coastguard Worker {
616*61046927SAndroid Build Coastguard Worker va_list args;
617*61046927SAndroid Build Coastguard Worker va_start(args, fmt);
618*61046927SAndroid Build Coastguard Worker tu_cs_emit_debug_magic_strv((struct tu_cs *) cs, CP_NOP_END, fmt, args);
619*61046927SAndroid Build Coastguard Worker va_end(args);
620*61046927SAndroid Build Coastguard Worker }
621