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 36extern "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 45enum 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 58struct zink_descriptor_refs { 59 struct util_dynarray refs; 60}; 61 62 63/* hashes of all the named types in a given state */ 64struct zink_descriptor_state { 65 bool valid[ZINK_DESCRIPTOR_TYPES]; 66 uint32_t state[ZINK_DESCRIPTOR_TYPES]; 67}; 68 69enum 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 78enum 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 87struct hash_table; 88 89struct zink_context; 90struct zink_image_view; 91struct zink_program; 92struct zink_resource; 93struct zink_sampler; 94struct zink_sampler_view; 95struct zink_shader; 96struct zink_screen; 97 98 99struct zink_descriptor_state_key { 100 bool exists[ZINK_SHADER_COUNT]; 101 uint32_t state[ZINK_SHADER_COUNT]; 102}; 103 104struct zink_descriptor_layout_key { 105 unsigned num_bindings; 106 VkDescriptorSetLayoutBinding *bindings; 107}; 108 109struct zink_descriptor_layout { 110 VkDescriptorSetLayout layout; 111}; 112 113struct 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 120struct zink_descriptor_reference { 121 void **ref; 122 bool *invalid; 123}; 124 125struct 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 158struct 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 169struct zink_batch_descriptor_data { 170 struct set *desc_sets; 171}; 172 173static inline enum zink_descriptor_size_index 174zink_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 195static inline enum zink_descriptor_size_index_compact 196zink_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 217static inline enum zink_descriptor_size_index 218zink_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 234static inline enum zink_descriptor_size_index_compact 235zink_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} 248bool 249zink_descriptor_layouts_init(struct zink_context *ctx); 250 251void 252zink_descriptor_layouts_deinit(struct zink_context *ctx); 253 254uint32_t 255zink_get_sampler_view_hash(struct zink_context *ctx, struct zink_sampler_view *sampler_view, bool is_buffer); 256uint32_t 257zink_get_image_view_hash(struct zink_context *ctx, struct zink_image_view *image_view, bool is_buffer); 258bool 259zink_descriptor_util_alloc_sets(struct zink_screen *screen, VkDescriptorSetLayout dsl, VkDescriptorPool pool, VkDescriptorSet *sets, unsigned num_sets); 260struct zink_descriptor_layout * 261zink_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); 264struct zink_descriptor_pool_key * 265zink_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); 268void 269zink_descriptor_util_init_fbfetch(struct zink_context *ctx); 270bool 271zink_descriptor_util_push_layouts_get(struct zink_context *ctx, struct zink_descriptor_layout **dsls, struct zink_descriptor_layout_key **layout_keys); 272VkImageLayout 273zink_descriptor_util_image_layout_eval(const struct zink_context *ctx, const struct zink_resource *res, bool is_compute); 274void 275zink_descriptors_init_bindless(struct zink_context *ctx); 276void 277zink_descriptors_deinit_bindless(struct zink_context *ctx); 278void 279zink_descriptors_update_bindless(struct zink_context *ctx); 280/* these two can't be called in lazy mode */ 281void 282zink_descriptor_set_refs_clear(struct zink_descriptor_refs *refs, void *ptr); 283void 284zink_descriptor_set_recycle(struct zink_descriptor_set *zds); 285 286 287 288 289 290bool 291zink_descriptor_program_init(struct zink_context *ctx, struct zink_program *pg); 292 293void 294zink_descriptor_program_deinit(struct zink_context *ctx, struct zink_program *pg); 295 296void 297zink_descriptors_update(struct zink_context *ctx, bool is_compute); 298 299 300void 301zink_context_invalidate_descriptor_state(struct zink_context *ctx, enum pipe_shader_type shader, enum zink_descriptor_type type, unsigned, unsigned); 302 303uint32_t 304zink_get_sampler_view_hash(struct zink_context *ctx, struct zink_sampler_view *sampler_view, bool is_buffer); 305uint32_t 306zink_get_image_view_hash(struct zink_context *ctx, struct zink_image_view *image_view, bool is_buffer); 307struct zink_resource * 308zink_get_resource_for_descriptor(struct zink_context *ctx, enum zink_descriptor_type type, enum pipe_shader_type shader, int idx); 309 310void 311zink_batch_descriptor_deinit(struct zink_screen *screen, struct zink_batch_state *bs); 312void 313zink_batch_descriptor_reset(struct zink_screen *screen, struct zink_batch_state *bs); 314bool 315zink_batch_descriptor_init(struct zink_screen *screen, struct zink_batch_state *bs); 316 317bool 318zink_descriptors_init(struct zink_context *ctx); 319 320void 321zink_descriptors_deinit(struct zink_context *ctx); 322 323//LAZY 324bool 325zink_descriptor_program_init_lazy(struct zink_context *ctx, struct zink_program *pg); 326 327void 328zink_descriptor_program_deinit_lazy(struct zink_context *ctx, struct zink_program *pg); 329 330void 331zink_descriptors_update_lazy(struct zink_context *ctx, bool is_compute); 332 333 334void 335zink_context_invalidate_descriptor_state_lazy(struct zink_context *ctx, enum pipe_shader_type shader, enum zink_descriptor_type type, unsigned, unsigned); 336 337void 338zink_batch_descriptor_deinit_lazy(struct zink_screen *screen, struct zink_batch_state *bs); 339void 340zink_batch_descriptor_reset_lazy(struct zink_screen *screen, struct zink_batch_state *bs); 341bool 342zink_batch_descriptor_init_lazy(struct zink_screen *screen, struct zink_batch_state *bs); 343 344bool 345zink_descriptors_init_lazy(struct zink_context *ctx); 346 347void 348zink_descriptors_deinit_lazy(struct zink_context *ctx); 349 350void 351zink_descriptor_set_update_lazy(struct zink_context *ctx, struct zink_program *pg, enum zink_descriptor_type type, VkDescriptorSet set); 352void 353zink_descriptors_update_lazy_masked(struct zink_context *ctx, bool is_compute, uint8_t changed_sets, uint8_t bind_sets); 354VkDescriptorSet 355zink_descriptors_alloc_lazy_push(struct zink_context *ctx); 356#ifdef __cplusplus 357} 358#endif 359 360#endif 361