1 /*
2 * Copyright © 2020 Mike Blumenkrantz
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 DEALINGS
21 * IN THE SOFTWARE.
22 *
23 * Authors:
24 * Mike Blumenkrantz <michael.blumenkrantz@gmail.com>
25 */
26
27 #ifndef ZINK_DESCRIPTOR_H
28 # define ZINK_DESCRIPTOR_H
29 #include <vulkan/vulkan.h>
30 #include "util/u_dynarray.h"
31 #include "util/u_inlines.h"
32 #include "util/simple_mtx.h"
33
34 #include "zink_batch.h"
35 #ifdef __cplusplus
36 extern "C" {
37 #endif
38
39 #ifndef ZINK_SHADER_COUNT
40 #define ZINK_SHADER_COUNT (PIPE_SHADER_TYPES - 1)
41 #endif
42
43 #define ZINK_DESCRIPTOR_COMPACT 2
44
45 enum zink_descriptor_type {
46 ZINK_DESCRIPTOR_TYPE_UBO,
47 ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW,
48 ZINK_DESCRIPTOR_TYPE_SSBO,
49 ZINK_DESCRIPTOR_TYPE_IMAGE,
50 ZINK_DESCRIPTOR_TYPES,
51 ZINK_DESCRIPTOR_BINDLESS,
52 };
53
54 #define ZINK_MAX_DESCRIPTORS_PER_TYPE (32 * ZINK_SHADER_COUNT)
55
56 #define ZINK_BINDLESS_IS_BUFFER(HANDLE) (HANDLE >= ZINK_MAX_BINDLESS_HANDLES)
57
58 struct zink_descriptor_refs {
59 struct util_dynarray refs;
60 };
61
62
63 /* hashes of all the named types in a given state */
64 struct zink_descriptor_state {
65 bool valid[ZINK_DESCRIPTOR_TYPES];
66 uint32_t state[ZINK_DESCRIPTOR_TYPES];
67 };
68
69 enum zink_descriptor_size_index {
70 ZDS_INDEX_UBO,
71 ZDS_INDEX_COMBINED_SAMPLER,
72 ZDS_INDEX_UNIFORM_TEXELS,
73 ZDS_INDEX_STORAGE_BUFFER,
74 ZDS_INDEX_STORAGE_IMAGE,
75 ZDS_INDEX_STORAGE_TEXELS,
76 };
77
78 enum zink_descriptor_size_index_compact {
79 ZDS_INDEX_COMP_UBO,
80 ZDS_INDEX_COMP_STORAGE_BUFFER,
81 ZDS_INDEX_COMP_COMBINED_SAMPLER,
82 ZDS_INDEX_COMP_UNIFORM_TEXELS,
83 ZDS_INDEX_COMP_STORAGE_IMAGE,
84 ZDS_INDEX_COMP_STORAGE_TEXELS,
85 };
86
87 struct hash_table;
88
89 struct zink_context;
90 struct zink_image_view;
91 struct zink_program;
92 struct zink_resource;
93 struct zink_sampler;
94 struct zink_sampler_view;
95 struct zink_shader;
96 struct zink_screen;
97
98
99 struct zink_descriptor_state_key {
100 bool exists[ZINK_SHADER_COUNT];
101 uint32_t state[ZINK_SHADER_COUNT];
102 };
103
104 struct zink_descriptor_layout_key {
105 unsigned num_bindings;
106 VkDescriptorSetLayoutBinding *bindings;
107 };
108
109 struct zink_descriptor_layout {
110 VkDescriptorSetLayout layout;
111 };
112
113 struct zink_descriptor_pool_key {
114 unsigned use_count;
115 unsigned num_type_sizes;
116 struct zink_descriptor_layout_key *layout;
117 VkDescriptorPoolSize sizes[4];
118 };
119
120 struct zink_descriptor_reference {
121 void **ref;
122 bool *invalid;
123 };
124
125 struct zink_descriptor_data {
126 struct zink_descriptor_state gfx_descriptor_states[ZINK_SHADER_COUNT]; // keep incremental hashes here
127 struct zink_descriptor_state descriptor_states[2]; // gfx, compute
128 struct zink_descriptor_state compact_gfx_descriptor_states[ZINK_SHADER_COUNT]; // keep incremental hashes here
129 struct zink_descriptor_state compact_descriptor_states[2]; // gfx, compute
130 struct hash_table *descriptor_pools[ZINK_DESCRIPTOR_TYPES];
131
132 struct zink_descriptor_layout_key *push_layout_keys[2]; //gfx, compute
133 struct zink_descriptor_pool *push_pool[2]; //gfx, compute
134 struct zink_descriptor_layout *push_dsl[2]; //gfx, compute
135 VkDescriptorUpdateTemplate push_template[2]; //gfx, compute
136 uint8_t last_push_usage[2];
137 bool push_valid[2];
138 uint32_t push_state[2];
139 bool gfx_push_valid[ZINK_SHADER_COUNT];
140 uint32_t gfx_push_state[ZINK_SHADER_COUNT];
141 struct zink_descriptor_set *last_set[2];
142
143 VkDescriptorPool dummy_pool;
144 struct zink_descriptor_layout *dummy_dsl;
145 VkDescriptorUpdateTemplate dummy_template;
146 VkDescriptorSet dummy_set;
147
148 VkDescriptorSetLayout bindless_layout;
149 VkDescriptorPool bindless_pool;
150 VkDescriptorSet bindless_set;
151 bool bindless_bound;
152
153 bool changed[2][ZINK_DESCRIPTOR_TYPES + 1];
154 bool has_fbfetch;
155 struct zink_program *pg[2]; //gfx, compute
156 };
157
158 struct zink_program_descriptor_data {
159 uint8_t push_usage;
160 bool bindless;
161 bool fbfetch;
162 uint8_t binding_usage;
163 uint8_t real_binding_usage;
164 struct zink_descriptor_pool_key *pool_key[ZINK_DESCRIPTOR_TYPES]; //push set doesn't need one
165 struct zink_descriptor_layout *layouts[ZINK_DESCRIPTOR_TYPES + 1];
166 VkDescriptorUpdateTemplate templates[ZINK_DESCRIPTOR_TYPES + 1];
167 };
168
169 struct zink_batch_descriptor_data {
170 struct set *desc_sets;
171 };
172
173 static inline enum zink_descriptor_size_index
zink_vktype_to_size_idx(VkDescriptorType type)174 zink_vktype_to_size_idx(VkDescriptorType type)
175 {
176 switch (type) {
177 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
178 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
179 return ZDS_INDEX_UBO;
180 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
181 return ZDS_INDEX_COMBINED_SAMPLER;
182 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
183 return ZDS_INDEX_UNIFORM_TEXELS;
184 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
185 return ZDS_INDEX_STORAGE_BUFFER;
186 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
187 return ZDS_INDEX_STORAGE_IMAGE;
188 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
189 return ZDS_INDEX_STORAGE_TEXELS;
190 default: break;
191 }
192 unreachable("unknown type");
193 }
194
195 static inline enum zink_descriptor_size_index_compact
zink_vktype_to_size_idx_comp(VkDescriptorType type)196 zink_vktype_to_size_idx_comp(VkDescriptorType type)
197 {
198 switch (type) {
199 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
200 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
201 return ZDS_INDEX_COMP_UBO;
202 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
203 return ZDS_INDEX_COMP_COMBINED_SAMPLER;
204 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
205 return ZDS_INDEX_COMP_UNIFORM_TEXELS;
206 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
207 return ZDS_INDEX_COMP_STORAGE_BUFFER;
208 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
209 return ZDS_INDEX_COMP_STORAGE_IMAGE;
210 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
211 return ZDS_INDEX_COMP_STORAGE_TEXELS;
212 default: break;
213 }
214 unreachable("unknown type");
215 }
216
217 static inline enum zink_descriptor_size_index
zink_descriptor_type_to_size_idx(enum zink_descriptor_type type)218 zink_descriptor_type_to_size_idx(enum zink_descriptor_type type)
219 {
220 switch (type) {
221 case ZINK_DESCRIPTOR_TYPE_UBO:
222 return ZDS_INDEX_UBO;
223 case ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW:
224 return ZDS_INDEX_COMBINED_SAMPLER;
225 case ZINK_DESCRIPTOR_TYPE_SSBO:
226 return ZDS_INDEX_STORAGE_BUFFER;
227 case ZINK_DESCRIPTOR_TYPE_IMAGE:
228 return ZDS_INDEX_STORAGE_IMAGE;
229 default: break;
230 }
231 unreachable("unknown type");
232 }
233
234 static inline enum zink_descriptor_size_index_compact
zink_descriptor_type_to_size_idx_comp(enum zink_descriptor_type type)235 zink_descriptor_type_to_size_idx_comp(enum zink_descriptor_type type)
236 {
237 switch (type) {
238 case ZINK_DESCRIPTOR_TYPE_UBO:
239 return ZDS_INDEX_COMP_UBO;
240 case ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW:
241 return ZDS_INDEX_COMP_COMBINED_SAMPLER;
242 case ZINK_DESCRIPTOR_TYPE_SSBO:
243 case ZINK_DESCRIPTOR_TYPE_IMAGE:
244 default: break;
245 }
246 unreachable("unknown type");
247 }
248 bool
249 zink_descriptor_layouts_init(struct zink_context *ctx);
250
251 void
252 zink_descriptor_layouts_deinit(struct zink_context *ctx);
253
254 uint32_t
255 zink_get_sampler_view_hash(struct zink_context *ctx, struct zink_sampler_view *sampler_view, bool is_buffer);
256 uint32_t
257 zink_get_image_view_hash(struct zink_context *ctx, struct zink_image_view *image_view, bool is_buffer);
258 bool
259 zink_descriptor_util_alloc_sets(struct zink_screen *screen, VkDescriptorSetLayout dsl, VkDescriptorPool pool, VkDescriptorSet *sets, unsigned num_sets);
260 struct zink_descriptor_layout *
261 zink_descriptor_util_layout_get(struct zink_context *ctx, enum zink_descriptor_type type,
262 VkDescriptorSetLayoutBinding *bindings, unsigned num_bindings,
263 struct zink_descriptor_layout_key **layout_key);
264 struct zink_descriptor_pool_key *
265 zink_descriptor_util_pool_key_get(struct zink_context *ctx, enum zink_descriptor_type type,
266 struct zink_descriptor_layout_key *layout_key,
267 VkDescriptorPoolSize *sizes, unsigned num_type_sizes);
268 void
269 zink_descriptor_util_init_fbfetch(struct zink_context *ctx);
270 bool
271 zink_descriptor_util_push_layouts_get(struct zink_context *ctx, struct zink_descriptor_layout **dsls, struct zink_descriptor_layout_key **layout_keys);
272 VkImageLayout
273 zink_descriptor_util_image_layout_eval(const struct zink_context *ctx, const struct zink_resource *res, bool is_compute);
274 void
275 zink_descriptors_init_bindless(struct zink_context *ctx);
276 void
277 zink_descriptors_deinit_bindless(struct zink_context *ctx);
278 void
279 zink_descriptors_update_bindless(struct zink_context *ctx);
280 /* these two can't be called in lazy mode */
281 void
282 zink_descriptor_set_refs_clear(struct zink_descriptor_refs *refs, void *ptr);
283 void
284 zink_descriptor_set_recycle(struct zink_descriptor_set *zds);
285
286
287
288
289
290 bool
291 zink_descriptor_program_init(struct zink_context *ctx, struct zink_program *pg);
292
293 void
294 zink_descriptor_program_deinit(struct zink_context *ctx, struct zink_program *pg);
295
296 void
297 zink_descriptors_update(struct zink_context *ctx, bool is_compute);
298
299
300 void
301 zink_context_invalidate_descriptor_state(struct zink_context *ctx, enum pipe_shader_type shader, enum zink_descriptor_type type, unsigned, unsigned);
302
303 uint32_t
304 zink_get_sampler_view_hash(struct zink_context *ctx, struct zink_sampler_view *sampler_view, bool is_buffer);
305 uint32_t
306 zink_get_image_view_hash(struct zink_context *ctx, struct zink_image_view *image_view, bool is_buffer);
307 struct zink_resource *
308 zink_get_resource_for_descriptor(struct zink_context *ctx, enum zink_descriptor_type type, enum pipe_shader_type shader, int idx);
309
310 void
311 zink_batch_descriptor_deinit(struct zink_screen *screen, struct zink_batch_state *bs);
312 void
313 zink_batch_descriptor_reset(struct zink_screen *screen, struct zink_batch_state *bs);
314 bool
315 zink_batch_descriptor_init(struct zink_screen *screen, struct zink_batch_state *bs);
316
317 bool
318 zink_descriptors_init(struct zink_context *ctx);
319
320 void
321 zink_descriptors_deinit(struct zink_context *ctx);
322
323 //LAZY
324 bool
325 zink_descriptor_program_init_lazy(struct zink_context *ctx, struct zink_program *pg);
326
327 void
328 zink_descriptor_program_deinit_lazy(struct zink_context *ctx, struct zink_program *pg);
329
330 void
331 zink_descriptors_update_lazy(struct zink_context *ctx, bool is_compute);
332
333
334 void
335 zink_context_invalidate_descriptor_state_lazy(struct zink_context *ctx, enum pipe_shader_type shader, enum zink_descriptor_type type, unsigned, unsigned);
336
337 void
338 zink_batch_descriptor_deinit_lazy(struct zink_screen *screen, struct zink_batch_state *bs);
339 void
340 zink_batch_descriptor_reset_lazy(struct zink_screen *screen, struct zink_batch_state *bs);
341 bool
342 zink_batch_descriptor_init_lazy(struct zink_screen *screen, struct zink_batch_state *bs);
343
344 bool
345 zink_descriptors_init_lazy(struct zink_context *ctx);
346
347 void
348 zink_descriptors_deinit_lazy(struct zink_context *ctx);
349
350 void
351 zink_descriptor_set_update_lazy(struct zink_context *ctx, struct zink_program *pg, enum zink_descriptor_type type, VkDescriptorSet set);
352 void
353 zink_descriptors_update_lazy_masked(struct zink_context *ctx, bool is_compute, uint8_t changed_sets, uint8_t bind_sets);
354 VkDescriptorSet
355 zink_descriptors_alloc_lazy_push(struct zink_context *ctx);
356 #ifdef __cplusplus
357 }
358 #endif
359
360 #endif
361