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 43enum 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 56struct zink_descriptor_refs { 57 struct util_dynarray refs; 58}; 59 60 61/* hashes of all the named types in a given state */ 62struct zink_descriptor_state { 63 bool valid[ZINK_DESCRIPTOR_TYPES]; 64 uint32_t state[ZINK_DESCRIPTOR_TYPES]; 65}; 66 67enum 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 76struct hash_table; 77 78struct zink_context; 79struct zink_image_view; 80struct zink_program; 81struct zink_resource; 82struct zink_sampler; 83struct zink_sampler_view; 84struct zink_shader; 85struct zink_screen; 86 87 88struct zink_descriptor_state_key { 89 bool exists[ZINK_SHADER_COUNT]; 90 uint32_t state[ZINK_SHADER_COUNT]; 91}; 92 93struct zink_descriptor_layout_key { 94 unsigned num_descriptors; 95 VkDescriptorSetLayoutBinding *bindings; 96 unsigned use_count; 97}; 98 99struct zink_descriptor_layout { 100 VkDescriptorSetLayout layout; 101 VkDescriptorUpdateTemplateKHR desc_template; 102}; 103 104struct zink_descriptor_pool_key { 105 struct zink_descriptor_layout_key *layout; 106 unsigned num_type_sizes; 107 VkDescriptorPoolSize *sizes; 108}; 109 110struct zink_descriptor_reference { 111 void **ref; 112 bool *invalid; 113}; 114 115struct 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 144struct 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 155struct zink_batch_descriptor_data { 156 struct set *desc_sets; 157}; 158 159static inline enum zink_descriptor_size_index 160zink_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 181static inline enum zink_descriptor_size_index 182zink_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} 197unsigned 198zink_descriptor_program_num_sizes(struct zink_program *pg, enum zink_descriptor_type type); 199bool 200zink_descriptor_layouts_init(struct zink_context *ctx); 201 202void 203zink_descriptor_layouts_deinit(struct zink_context *ctx); 204 205uint32_t 206zink_get_sampler_view_hash(struct zink_context *ctx, struct zink_sampler_view *sampler_view, bool is_buffer); 207uint32_t 208zink_get_image_view_hash(struct zink_context *ctx, struct zink_image_view *image_view, bool is_buffer); 209bool 210zink_descriptor_util_alloc_sets(struct zink_screen *screen, VkDescriptorSetLayout dsl, VkDescriptorPool pool, VkDescriptorSet *sets, unsigned num_sets); 211struct zink_descriptor_layout * 212zink_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); 215void 216zink_descriptor_util_init_fbfetch(struct zink_context *ctx); 217bool 218zink_descriptor_util_push_layouts_get(struct zink_context *ctx, struct zink_descriptor_layout **dsls, struct zink_descriptor_layout_key **layout_keys); 219void 220zink_descriptor_util_init_null_set(struct zink_context *ctx, VkDescriptorSet desc_set); 221VkImageLayout 222zink_descriptor_util_image_layout_eval(const struct zink_resource *res, bool is_compute); 223void 224zink_descriptors_init_bindless(struct zink_context *ctx); 225void 226zink_descriptors_deinit_bindless(struct zink_context *ctx); 227void 228zink_descriptors_update_bindless(struct zink_context *ctx); 229/* these two can't be called in lazy mode */ 230void 231zink_descriptor_set_refs_clear(struct zink_descriptor_refs *refs, void *ptr); 232void 233zink_descriptor_set_recycle(struct zink_descriptor_set *zds); 234 235 236 237 238 239bool 240zink_descriptor_program_init(struct zink_context *ctx, struct zink_program *pg); 241 242void 243zink_descriptor_program_deinit(struct zink_screen *screen, struct zink_program *pg); 244 245void 246zink_descriptors_update(struct zink_context *ctx, bool is_compute); 247 248 249void 250zink_context_invalidate_descriptor_state(struct zink_context *ctx, enum pipe_shader_type shader, enum zink_descriptor_type type, unsigned, unsigned); 251 252uint32_t 253zink_get_sampler_view_hash(struct zink_context *ctx, struct zink_sampler_view *sampler_view, bool is_buffer); 254uint32_t 255zink_get_image_view_hash(struct zink_context *ctx, struct zink_image_view *image_view, bool is_buffer); 256struct zink_resource * 257zink_get_resource_for_descriptor(struct zink_context *ctx, enum zink_descriptor_type type, enum pipe_shader_type shader, int idx); 258 259void 260zink_batch_descriptor_deinit(struct zink_screen *screen, struct zink_batch_state *bs); 261void 262zink_batch_descriptor_reset(struct zink_screen *screen, struct zink_batch_state *bs); 263bool 264zink_batch_descriptor_init(struct zink_screen *screen, struct zink_batch_state *bs); 265 266bool 267zink_descriptors_init(struct zink_context *ctx); 268 269void 270zink_descriptors_deinit(struct zink_context *ctx); 271 272//LAZY 273bool 274zink_descriptor_program_init_lazy(struct zink_context *ctx, struct zink_program *pg); 275 276void 277zink_descriptor_program_deinit_lazy(struct zink_screen *screen, struct zink_program *pg); 278 279void 280zink_descriptors_update_lazy(struct zink_context *ctx, bool is_compute); 281 282 283void 284zink_context_invalidate_descriptor_state_lazy(struct zink_context *ctx, enum pipe_shader_type shader, enum zink_descriptor_type type, unsigned, unsigned); 285 286void 287zink_batch_descriptor_deinit_lazy(struct zink_screen *screen, struct zink_batch_state *bs); 288void 289zink_batch_descriptor_reset_lazy(struct zink_screen *screen, struct zink_batch_state *bs); 290bool 291zink_batch_descriptor_init_lazy(struct zink_screen *screen, struct zink_batch_state *bs); 292 293bool 294zink_descriptors_init_lazy(struct zink_context *ctx); 295 296void 297zink_descriptors_deinit_lazy(struct zink_context *ctx); 298 299void 300zink_descriptor_set_update_lazy(struct zink_context *ctx, struct zink_program *pg, enum zink_descriptor_type type, VkDescriptorSet set); 301void 302zink_descriptors_update_lazy_masked(struct zink_context *ctx, bool is_compute, uint8_t changed_sets, uint8_t bind_sets); 303VkDescriptorSet 304zink_descriptors_alloc_lazy_push(struct zink_context *ctx); 305#ifdef __cplusplus 306} 307#endif 308 309#endif 310