• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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