2 * Copyright © 2019 Google LLC
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
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
27 tu_cmd_stream_init(struct tu_cmd_stream
*stream
)
29 stream
->start
= stream
->cur
= stream
->end
= NULL
;
31 stream
->entry_count
= stream
->entry_capacity
= 0;
32 stream
->entries
= NULL
;
34 stream
->bo_count
= stream
->bo_capacity
= 0;
39 tu_cmd_stream_finish(struct tu_device
*dev
, struct tu_cmd_stream
*stream
)
41 for (uint32_t i
= 0; i
< stream
->bo_count
; ++i
) {
42 tu_bo_finish(dev
, stream
->bos
[i
]);
46 free(stream
->entries
);
51 tu_cmd_stream_begin(struct tu_device
*dev
,
52 struct tu_cmd_stream
*stream
,
53 uint32_t reserve_size
)
57 if (stream
->end
- stream
->cur
< reserve_size
) {
58 if (stream
->bo_count
== stream
->bo_capacity
) {
59 uint32_t new_capacity
= MAX2(4, 2 * stream
->bo_capacity
);
60 struct tu_bo
**new_bos
=
61 realloc(stream
->bos
, new_capacity
* sizeof(struct tu_bo
*));
65 stream
->bo_capacity
= new_capacity
;
66 stream
->bos
= new_bos
;
69 uint32_t new_size
= MAX2(16384, reserve_size
* sizeof(uint32_t));
72 MAX2(new_size
, stream
->bos
[stream
->bo_count
- 1]->size
* 2);
74 struct tu_bo
*new_bo
= malloc(sizeof(struct tu_bo
));
78 VkResult result
= tu_bo_init_new(dev
, new_bo
, new_size
);
79 if (result
!= VK_SUCCESS
) {
84 result
= tu_bo_map(dev
, new_bo
);
85 if (result
!= VK_SUCCESS
) {
86 tu_bo_finish(dev
, new_bo
);
91 stream
->bos
[stream
->bo_count
] = new_bo
;
94 stream
->start
= stream
->cur
= (uint32_t *) new_bo
->map
;
95 stream
->end
= stream
->start
+ new_bo
->size
/ sizeof(uint32_t);
97 stream
->start
= stream
->cur
;
103 tu_cmd_stream_end(struct tu_cmd_stream
*stream
)
105 if (stream
->start
== stream
->cur
)
108 if (stream
->entry_capacity
== stream
->entry_count
) {
109 uint32_t new_capacity
= MAX2(stream
->entry_capacity
* 2, 4);
110 struct tu_cmd_stream_entry
*new_entries
= realloc(
111 stream
->entries
, new_capacity
* sizeof(struct tu_cmd_stream_entry
));
115 stream
->entries
= new_entries
;
116 stream
->entry_capacity
= new_capacity
;
119 assert(stream
->bo_count
);
121 struct tu_cmd_stream_entry entry
;
122 entry
.bo
= stream
->bos
[stream
->bo_count
- 1];
123 entry
.size
= (stream
->cur
- stream
->start
) * sizeof(uint32_t);
125 (stream
->start
- (uint32_t *) entry
.bo
->map
) * sizeof(uint32_t);
127 stream
->entries
[stream
->entry_count
] = entry
;
128 ++stream
->entry_count
;
134 tu_cmd_stream_reset(struct tu_device
*dev
, struct tu_cmd_stream
*stream
)
136 for (uint32_t i
= 0; i
+ 1 < stream
->bo_count
; ++i
) {
137 tu_bo_finish(dev
, stream
->bos
[i
]);
138 free(stream
->bos
[i
]);
141 if (stream
->bo_count
) {
142 stream
->bos
[0] = stream
->bos
[stream
->bo_count
- 1];
143 stream
->bo_count
= 1;
145 stream
->start
= stream
->cur
= (uint32_t *) stream
->bos
[0]->map
;
146 stream
->end
= stream
->start
+ stream
->bos
[0]->size
/ sizeof(uint32_t);
149 stream
->entry_count
= 0;
153 tu_cs_check_space(struct tu_device
*dev
,
154 struct tu_cmd_stream
*stream
,
157 if (stream
->end
- stream
->cur
>= size
)
160 VkResult result
= tu_cmd_stream_end(stream
);
161 if (result
!= VK_SUCCESS
)
164 return tu_cmd_stream_begin(dev
, stream
, size
);