Blender V5.0
vk_descriptor_set_layouts.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2024 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
10#include "vk_backend.hh"
11
12namespace blender::gpu {
14{
15 vk_descriptor_set_layout_create_info_ = {};
16 vk_descriptor_set_layout_create_info_.sType =
17 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
18}
19
24
26 bool &r_created,
27 bool &r_needed)
28{
29 r_created = false;
30 r_needed = !info.bindings.is_empty();
31 if (r_needed == false) {
32 return VK_NULL_HANDLE;
33 }
34
35 std::scoped_lock mutex(mutex_);
36
37 VkDescriptorSetLayout *layout = vk_descriptor_set_layouts_.lookup_ptr(info);
38 if (layout) {
39 return *layout;
40 }
41
42 update_layout_bindings(info);
43 const VKDevice &device = VKBackend::get().device;
44 const bool use_descriptor_buffer = device.extensions_get().descriptor_buffer;
45
46 vk_descriptor_set_layout_create_info_.bindingCount = vk_descriptor_set_layout_bindings_.size();
47 vk_descriptor_set_layout_create_info_.pBindings = vk_descriptor_set_layout_bindings_.data();
48 if (use_descriptor_buffer) {
49 vk_descriptor_set_layout_create_info_.flags =
50 VK_DESCRIPTOR_SET_LAYOUT_CREATE_DESCRIPTOR_BUFFER_BIT_EXT;
51 }
52
53 VkDescriptorSetLayout vk_descriptor_set_layout = VK_NULL_HANDLE;
54 vkCreateDescriptorSetLayout(device.vk_handle(),
55 &vk_descriptor_set_layout_create_info_,
56 nullptr,
57 &vk_descriptor_set_layout);
58 BLI_assert(vk_descriptor_set_layout != VK_NULL_HANDLE);
59
60 vk_descriptor_set_layout_create_info_.bindingCount = 0;
61 vk_descriptor_set_layout_create_info_.pBindings = nullptr;
62 vk_descriptor_set_layout_bindings_.clear();
63 vk_descriptor_set_layouts_.add(info, vk_descriptor_set_layout);
64 r_created = true;
65
66 if (use_descriptor_buffer) {
67 descriptor_buffer_layouts_.add(
68 vk_descriptor_set_layout,
69 create_descriptor_buffer_layout(device, info, vk_descriptor_set_layout));
70 }
71
72 return vk_descriptor_set_layout;
73}
74
75void VKDescriptorSetLayouts::update_layout_bindings(const VKDescriptorSetLayoutInfo &info)
76{
77 BLI_assert(vk_descriptor_set_layout_bindings_.is_empty());
78 vk_descriptor_set_layout_bindings_.reserve(info.bindings.size());
79
80 uint32_t index = 0;
81 for (const VkDescriptorType &vk_descriptor_type : info.bindings) {
82 VkDescriptorSetLayoutBinding binding = {};
83 binding.binding = index++;
84 binding.descriptorCount = 1;
85 binding.descriptorType = vk_descriptor_type;
86 binding.pImmutableSamplers = VK_NULL_HANDLE;
87 binding.stageFlags = vk_descriptor_type == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT ?
88 VkShaderStageFlags(VK_SHADER_STAGE_FRAGMENT_BIT) :
89 info.vk_shader_stage_flags;
90 vk_descriptor_set_layout_bindings_.append(binding);
91 }
92}
93
95{
96 std::scoped_lock mutex(mutex_);
97 const VKDevice &device = VKBackend::get().device;
98 for (VkDescriptorSetLayout &vk_descriptor_set_layout : vk_descriptor_set_layouts_.values()) {
99 vkDestroyDescriptorSetLayout(device.vk_handle(), vk_descriptor_set_layout, nullptr);
100 }
101 vk_descriptor_set_layouts_.clear();
102}
103
104static void align_size(VkDeviceSize &r_size, VkDeviceSize alignment)
105{
106 if (alignment > 1) {
107 r_size = (r_size + alignment - 1) & ~(alignment - 1);
108 }
109}
110VKDescriptorBufferLayout VKDescriptorSetLayouts::create_descriptor_buffer_layout(
111 const VKDevice &device,
112 const VKDescriptorSetLayoutInfo &info,
113 VkDescriptorSetLayout vk_descriptor_set_layout) const
114{
115 const VkPhysicalDeviceDescriptorBufferPropertiesEXT &properties =
117 VKDescriptorBufferLayout result = {};
118
119 device.functions.vkGetDescriptorSetLayoutSize(
120 device.vk_handle(), vk_descriptor_set_layout, &result.size);
121 align_size(result.size, properties.descriptorBufferOffsetAlignment);
122
123 result.binding_offsets.resize(info.bindings.size());
124 for (uint32_t binding : IndexRange(info.bindings.size())) {
125 device.functions.vkGetDescriptorSetLayoutBindingOffset(
126 device.vk_handle(), vk_descriptor_set_layout, binding, &result.binding_offsets[binding]);
127 }
128
129 return result;
130}
131
132} // namespace blender::gpu
#define BLI_assert(a)
Definition BLI_assert.h:46
void append(const T &value)
bool is_empty() const
void reserve(const int64_t min_capacity)
int64_t size() const
bool is_empty() const
static VKBackend & get()
Definition vk_backend.hh:91
VkDescriptorSetLayout get_or_create(const VKDescriptorSetLayoutInfo &info, bool &r_created, bool &r_needed)
VkDevice vk_handle() const
Definition vk_device.hh:311
const VKExtensions & extensions_get() const
Definition vk_device.hh:371
const VkPhysicalDeviceDescriptorBufferPropertiesEXT & physical_device_descriptor_buffer_properties_get() const
Definition vk_device.hh:286
ThreadMutex mutex
static void align_size(VkDeviceSize &r_size, VkDeviceSize alignment)