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 enum zink_descriptor_type {
44    ZINK_DESCRIPTOR_TYPE_UBO,
45    ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW,
46    ZINK_DESCRIPTOR_TYPE_SSBO,
47    ZINK_DESCRIPTOR_TYPE_IMAGE,
48    ZINK_DESCRIPTOR_TYPES,
49    ZINK_DESCRIPTOR_BINDLESS,
50 };
51 
52 #define ZINK_MAX_DESCRIPTORS_PER_TYPE (32 * ZINK_SHADER_COUNT)
53 
54 #define ZINK_BINDLESS_IS_BUFFER(HANDLE) (HANDLE >= ZINK_MAX_BINDLESS_HANDLES)
55 
56 struct zink_descriptor_refs {
57    struct util_dynarray refs;
58 };
59 
60 
61 /* hashes of all the named types in a given state */
62 struct zink_descriptor_state {
63    bool valid[ZINK_DESCRIPTOR_TYPES];
64    uint32_t state[ZINK_DESCRIPTOR_TYPES];
65 };
66 
67 enum zink_descriptor_size_index {
68    ZDS_INDEX_UBO,
69    ZDS_INDEX_COMBINED_SAMPLER,
70    ZDS_INDEX_UNIFORM_TEXELS,
71    ZDS_INDEX_STORAGE_BUFFER,
72    ZDS_INDEX_STORAGE_IMAGE,
73    ZDS_INDEX_STORAGE_TEXELS,
74 };
75 
76 struct hash_table;
77 
78 struct zink_context;
79 struct zink_image_view;
80 struct zink_program;
81 struct zink_resource;
82 struct zink_sampler;
83 struct zink_sampler_view;
84 struct zink_shader;
85 struct zink_screen;
86 
87 
88 struct zink_descriptor_state_key {
89    bool exists[ZINK_SHADER_COUNT];
90    uint32_t state[ZINK_SHADER_COUNT];
91 };
92 
93 struct zink_descriptor_layout_key {
94    unsigned num_descriptors;
95    VkDescriptorSetLayoutBinding *bindings;
96    unsigned use_count;
97 };
98 
99 struct zink_descriptor_layout {
100    VkDescriptorSetLayout layout;
101    VkDescriptorUpdateTemplateKHR desc_template;
102 };
103 
104 struct zink_descriptor_pool_key {
105    struct zink_descriptor_layout_key *layout;
106    unsigned num_type_sizes;
107    VkDescriptorPoolSize *sizes;
108 };
109 
110 struct zink_descriptor_reference {
111    void **ref;
112    bool *invalid;
113 };
114 
115 struct zink_descriptor_data {
116    struct zink_descriptor_state gfx_descriptor_states[ZINK_SHADER_COUNT]; // keep incremental hashes here
117    struct zink_descriptor_state descriptor_states[2]; // gfx, compute
118    struct hash_table *descriptor_pools[ZINK_DESCRIPTOR_TYPES];
119 
120    struct zink_descriptor_layout_key *push_layout_keys[2]; //gfx, compute
121    struct zink_descriptor_pool *push_pool[2]; //gfx, compute
122    struct zink_descriptor_layout *push_dsl[2]; //gfx, compute
123    uint8_t last_push_usage[2];
124    bool push_valid[2];
125    uint32_t push_state[2];
126    bool gfx_push_valid[ZINK_SHADER_COUNT];
127    uint32_t gfx_push_state[ZINK_SHADER_COUNT];
128    struct zink_descriptor_set *last_set[2];
129 
130    VkDescriptorPool dummy_pool;
131    struct zink_descriptor_layout *dummy_dsl;
132    VkDescriptorSet dummy_set;
133 
134    VkDescriptorSetLayout bindless_layout;
135    VkDescriptorPool bindless_pool;
136    VkDescriptorSet bindless_set;
137    bool bindless_bound;
138 
139    bool changed[2][ZINK_DESCRIPTOR_TYPES + 1];
140    bool has_fbfetch;
141    struct zink_program *pg[2]; //gfx, compute
142 };
143 
144 struct zink_program_descriptor_data {
145    uint8_t push_usage;
146    bool bindless;
147    VkDescriptorPoolSize sizes[6]; //zink_descriptor_size_index
148    struct zink_descriptor_layout_key *layout_key[ZINK_DESCRIPTOR_TYPES]; //push set doesn't need one
149    bool fbfetch;
150    uint8_t binding_usage;
151    struct zink_descriptor_layout *layouts[ZINK_DESCRIPTOR_TYPES + 1];
152    VkDescriptorUpdateTemplateKHR push_template;
153 };
154 
155 struct zink_batch_descriptor_data {
156    struct set *desc_sets;
157 };
158 
159 static inline enum zink_descriptor_size_index
zink_vktype_to_size_idx(VkDescriptorType type)160 zink_vktype_to_size_idx(VkDescriptorType type)
161 {
162    switch (type) {
163    case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
164    case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
165       return ZDS_INDEX_UBO;
166    case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
167       return ZDS_INDEX_COMBINED_SAMPLER;
168    case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
169       return ZDS_INDEX_UNIFORM_TEXELS;
170    case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
171       return ZDS_INDEX_STORAGE_BUFFER;
172    case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
173       return ZDS_INDEX_STORAGE_IMAGE;
174    case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
175       return ZDS_INDEX_STORAGE_TEXELS;
176    default: break;
177    }
178    unreachable("unknown type");
179 }
180 
181 static inline enum zink_descriptor_size_index
zink_descriptor_type_to_size_idx(enum zink_descriptor_type type)182 zink_descriptor_type_to_size_idx(enum zink_descriptor_type type)
183 {
184    switch (type) {
185    case ZINK_DESCRIPTOR_TYPE_UBO:
186       return ZDS_INDEX_UBO;
187    case ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW:
188       return ZDS_INDEX_COMBINED_SAMPLER;
189    case ZINK_DESCRIPTOR_TYPE_SSBO:
190       return ZDS_INDEX_STORAGE_BUFFER;
191    case ZINK_DESCRIPTOR_TYPE_IMAGE:
192       return ZDS_INDEX_STORAGE_IMAGE;
193    default: break;
194    }
195    unreachable("unknown type");
196 }
197 unsigned
198 zink_descriptor_program_num_sizes(struct zink_program *pg, enum zink_descriptor_type type);
199 bool
200 zink_descriptor_layouts_init(struct zink_context *ctx);
201 
202 void
203 zink_descriptor_layouts_deinit(struct zink_context *ctx);
204 
205 uint32_t
206 zink_get_sampler_view_hash(struct zink_context *ctx, struct zink_sampler_view *sampler_view, bool is_buffer);
207 uint32_t
208 zink_get_image_view_hash(struct zink_context *ctx, struct zink_image_view *image_view, bool is_buffer);
209 bool
210 zink_descriptor_util_alloc_sets(struct zink_screen *screen, VkDescriptorSetLayout dsl, VkDescriptorPool pool, VkDescriptorSet *sets, unsigned num_sets);
211 struct zink_descriptor_layout *
212 zink_descriptor_util_layout_get(struct zink_context *ctx, enum zink_descriptor_type type,
213                       VkDescriptorSetLayoutBinding *bindings, unsigned num_bindings,
214                       struct zink_descriptor_layout_key **layout_key);
215 void
216 zink_descriptor_util_init_fbfetch(struct zink_context *ctx);
217 bool
218 zink_descriptor_util_push_layouts_get(struct zink_context *ctx, struct zink_descriptor_layout **dsls, struct zink_descriptor_layout_key **layout_keys);
219 void
220 zink_descriptor_util_init_null_set(struct zink_context *ctx, VkDescriptorSet desc_set);
221 VkImageLayout
222 zink_descriptor_util_image_layout_eval(const struct zink_resource *res, bool is_compute);
223 void
224 zink_descriptors_init_bindless(struct zink_context *ctx);
225 void
226 zink_descriptors_deinit_bindless(struct zink_context *ctx);
227 void
228 zink_descriptors_update_bindless(struct zink_context *ctx);
229 /* these two can't be called in lazy mode */
230 void
231 zink_descriptor_set_refs_clear(struct zink_descriptor_refs *refs, void *ptr);
232 void
233 zink_descriptor_set_recycle(struct zink_descriptor_set *zds);
234 
235 
236 
237 
238 
239 bool
240 zink_descriptor_program_init(struct zink_context *ctx, struct zink_program *pg);
241 
242 void
243 zink_descriptor_program_deinit(struct zink_screen *screen, struct zink_program *pg);
244 
245 void
246 zink_descriptors_update(struct zink_context *ctx, bool is_compute);
247 
248 
249 void
250 zink_context_invalidate_descriptor_state(struct zink_context *ctx, enum pipe_shader_type shader, enum zink_descriptor_type type, unsigned, unsigned);
251 
252 uint32_t
253 zink_get_sampler_view_hash(struct zink_context *ctx, struct zink_sampler_view *sampler_view, bool is_buffer);
254 uint32_t
255 zink_get_image_view_hash(struct zink_context *ctx, struct zink_image_view *image_view, bool is_buffer);
256 struct zink_resource *
257 zink_get_resource_for_descriptor(struct zink_context *ctx, enum zink_descriptor_type type, enum pipe_shader_type shader, int idx);
258 
259 void
260 zink_batch_descriptor_deinit(struct zink_screen *screen, struct zink_batch_state *bs);
261 void
262 zink_batch_descriptor_reset(struct zink_screen *screen, struct zink_batch_state *bs);
263 bool
264 zink_batch_descriptor_init(struct zink_screen *screen, struct zink_batch_state *bs);
265 
266 bool
267 zink_descriptors_init(struct zink_context *ctx);
268 
269 void
270 zink_descriptors_deinit(struct zink_context *ctx);
271 
272 //LAZY
273 bool
274 zink_descriptor_program_init_lazy(struct zink_context *ctx, struct zink_program *pg);
275 
276 void
277 zink_descriptor_program_deinit_lazy(struct zink_screen *screen, struct zink_program *pg);
278 
279 void
280 zink_descriptors_update_lazy(struct zink_context *ctx, bool is_compute);
281 
282 
283 void
284 zink_context_invalidate_descriptor_state_lazy(struct zink_context *ctx, enum pipe_shader_type shader, enum zink_descriptor_type type, unsigned, unsigned);
285 
286 void
287 zink_batch_descriptor_deinit_lazy(struct zink_screen *screen, struct zink_batch_state *bs);
288 void
289 zink_batch_descriptor_reset_lazy(struct zink_screen *screen, struct zink_batch_state *bs);
290 bool
291 zink_batch_descriptor_init_lazy(struct zink_screen *screen, struct zink_batch_state *bs);
292 
293 bool
294 zink_descriptors_init_lazy(struct zink_context *ctx);
295 
296 void
297 zink_descriptors_deinit_lazy(struct zink_context *ctx);
298 
299 void
300 zink_descriptor_set_update_lazy(struct zink_context *ctx, struct zink_program *pg, enum zink_descriptor_type type, VkDescriptorSet set);
301 void
302 zink_descriptors_update_lazy_masked(struct zink_context *ctx, bool is_compute, uint8_t changed_sets, uint8_t bind_sets);
303 VkDescriptorSet
304 zink_descriptors_alloc_lazy_push(struct zink_context *ctx);
305 #ifdef __cplusplus
306 }
307 #endif
308 
309 #endif
310