turnip: run sed and clang-format on tu_cs
[mesa.git] / src / freedreno / vulkan / tu_cs.c
1 /*
2 * Copyright © 2019 Google LLC
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 */
23
24 #include "tu_cs.h"
25
26 void
27 tu_cs_init(struct tu_cs *cs)
28 {
29 cs->start = cs->cur = cs->end = NULL;
30
31 cs->entry_count = cs->entry_capacity = 0;
32 cs->entries = NULL;
33
34 cs->bo_count = cs->bo_capacity = 0;
35 cs->bos = NULL;
36 }
37
38 void
39 tu_cs_finish(struct tu_device *dev, struct tu_cs *cs)
40 {
41 for (uint32_t i = 0; i < cs->bo_count; ++i) {
42 tu_bo_finish(dev, cs->bos[i]);
43 free(cs->bos[i]);
44 }
45
46 free(cs->entries);
47 free(cs->bos);
48 }
49
50 VkResult
51 tu_cs_begin(struct tu_device *dev, struct tu_cs *cs, uint32_t reserve_size)
52 {
53 assert(reserve_size);
54
55 if (cs->end - cs->cur < reserve_size) {
56 if (cs->bo_count == cs->bo_capacity) {
57 uint32_t new_capacity = MAX2(4, 2 * cs->bo_capacity);
58 struct tu_bo **new_bos =
59 realloc(cs->bos, new_capacity * sizeof(struct tu_bo *));
60 if (!new_bos)
61 abort();
62
63 cs->bo_capacity = new_capacity;
64 cs->bos = new_bos;
65 }
66
67 uint32_t new_size = MAX2(16384, reserve_size * sizeof(uint32_t));
68 if (cs->bo_count)
69 new_size = MAX2(new_size, cs->bos[cs->bo_count - 1]->size * 2);
70
71 struct tu_bo *new_bo = malloc(sizeof(struct tu_bo));
72 if (!new_bo)
73 abort();
74
75 VkResult result = tu_bo_init_new(dev, new_bo, new_size);
76 if (result != VK_SUCCESS) {
77 free(new_bo);
78 return result;
79 }
80
81 result = tu_bo_map(dev, new_bo);
82 if (result != VK_SUCCESS) {
83 tu_bo_finish(dev, new_bo);
84 free(new_bo);
85 return result;
86 }
87
88 cs->bos[cs->bo_count] = new_bo;
89 ++cs->bo_count;
90
91 cs->start = cs->cur = (uint32_t *) new_bo->map;
92 cs->end = cs->start + new_bo->size / sizeof(uint32_t);
93 }
94 cs->start = cs->cur;
95
96 return VK_SUCCESS;
97 }
98
99 VkResult
100 tu_cs_end(struct tu_cs *cs)
101 {
102 if (cs->start == cs->cur)
103 return VK_SUCCESS;
104
105 if (cs->entry_capacity == cs->entry_count) {
106 uint32_t new_capacity = MAX2(cs->entry_capacity * 2, 4);
107 struct tu_cs_entry *new_entries =
108 realloc(cs->entries, new_capacity * sizeof(struct tu_cs_entry));
109 if (!new_entries)
110 abort(); /* TODO */
111
112 cs->entries = new_entries;
113 cs->entry_capacity = new_capacity;
114 }
115
116 assert(cs->bo_count);
117
118 struct tu_cs_entry entry;
119 entry.bo = cs->bos[cs->bo_count - 1];
120 entry.size = (cs->cur - cs->start) * sizeof(uint32_t);
121 entry.offset = (cs->start - (uint32_t *) entry.bo->map) * sizeof(uint32_t);
122
123 cs->entries[cs->entry_count] = entry;
124 ++cs->entry_count;
125
126 return VK_SUCCESS;
127 }
128
129 void
130 tu_cs_reset(struct tu_device *dev, struct tu_cs *cs)
131 {
132 for (uint32_t i = 0; i + 1 < cs->bo_count; ++i) {
133 tu_bo_finish(dev, cs->bos[i]);
134 free(cs->bos[i]);
135 }
136
137 if (cs->bo_count) {
138 cs->bos[0] = cs->bos[cs->bo_count - 1];
139 cs->bo_count = 1;
140
141 cs->start = cs->cur = (uint32_t *) cs->bos[0]->map;
142 cs->end = cs->start + cs->bos[0]->size / sizeof(uint32_t);
143 }
144
145 cs->entry_count = 0;
146 }
147
148 VkResult
149 tu_cs_check_space(struct tu_device *dev, struct tu_cs *cs, size_t size)
150 {
151 if (cs->end - cs->cur >= size)
152 return VK_SUCCESS;
153
154 VkResult result = tu_cs_end(cs);
155 if (result != VK_SUCCESS)
156 return result;
157
158 return tu_cs_begin(dev, cs, size);
159 }