#ifndef RT_VK_BINDLESS_REGISTRY_H #define RT_VK_BINDLESS_REGISTRY_H #include #include #include #include struct rt_vk_device; enum { RT_VK_INVALID_BINDLESS_HANDLE_VALUE = UINT32_MAX }; typedef enum { RT_VK_BINDLESS_HANDLE_TYPE_UNIFORM_BUFFER, RT_VK_BINDLESS_HANDLE_TYPE_STORAGE_BUFFER, RT_VK_BINDLESS_HANDLE_TYPE_SAMPLED_IMAGE, RT_VK_BINDLESS_HANDLE_TYPE_STORAGE_IMAGE, RT_VK_BINDLESS_HANDLE_TYPE_SAMPLER, } rt_vk_bindless_handle_type; /* Handle to a bindless resource. * The layout is: * | type : 3 | index : 29 | * MSB LSB */ typedef struct { uint32_t value; } rt_vk_bindless_handle; /* Utilities for bindless handles */ static RT_INLINE bool rtIsVkBindlessHandleValid(rt_vk_bindless_handle handle) { return handle.value != RT_VK_INVALID_BINDLESS_HANDLE_VALUE; } static RT_INLINE rt_vk_bindless_handle_type rtGetVkBindlessHandleType(rt_vk_bindless_handle handle) { return (handle.value >> 29) & 0x7; } static RT_INLINE uint32_t rtGetVkBindlessHandleIndex(rt_vk_bindless_handle handle) { return handle.value & ((1u << 29) - 1); } typedef struct { uint32_t *indices; uint32_t size; } rt_vk_bindless_reuse_stack; typedef struct { rt_vk_bindless_handle handle; /* Frame id on which the handle should be released */ uint32_t frame; } rt_vk_bindless_release_list_entry; /* Bindless registry manages the global descriptor set of bindless resources. */ typedef struct { struct rt_vk_device *dev; rt_mutex *mutex; VkDescriptorSetLayout bindless_set_layout; VkDescriptorPool bindless_set_pool; VkDescriptorSet bindless_set; uint32_t uniform_buffer_binding; uint32_t storage_buffer_binding; uint32_t sampled_image_binding; uint32_t storage_image_binding; uint32_t sampler_binding; rt_vk_bindless_reuse_stack uniform_buffer_reuse_stack; rt_vk_bindless_reuse_stack storage_buffer_reuse_stack; rt_vk_bindless_reuse_stack sampled_image_reuse_stack; rt_vk_bindless_reuse_stack storage_image_reuse_stack; rt_vk_bindless_reuse_stack sampler_reuse_stack; uint32_t next_uniform_buffer; uint32_t next_storage_buffer; uint32_t next_sampled_image; uint32_t next_storage_image; uint32_t next_sampler; rt_vk_bindless_release_list_entry *release_list; uint32_t release_list_length; } rt_vk_bindless_registry; typedef struct { rt_result result; rt_vk_bindless_registry bindless_registry; } rt_create_vk_bindless_registry_result; rt_create_vk_bindless_registry_result rtCreateVkBindlessRegistry(struct rt_vk_device *dev); void rtDestroyVkBindlessRegistry(rt_vk_bindless_registry *registry); void rtVkBindlessRegistryOnBeginFrame(rt_vk_bindless_registry *registry); rt_vk_bindless_handle rtStoreUniformBuffer(rt_vk_bindless_registry *registry, VkBuffer buffer); rt_vk_bindless_handle rtStoreStorageBuffer(rt_vk_bindless_registry *registry, VkBuffer buffer); rt_vk_bindless_handle rtStoreSampledImage(rt_vk_bindless_registry *registry, VkImageView image); rt_vk_bindless_handle rtStoreStorageImage(rt_vk_bindless_registry *registry, VkImageView image); rt_vk_bindless_handle rtStoreSampler(rt_vk_bindless_registry *registry, VkSampler sampler); void rtFreeBindlessResource(rt_vk_bindless_registry *registry, rt_vk_bindless_handle handle); #endif