Files
Vulkan-Samples/framework/core/descriptor_set.h
T
2025-09-04 10:54:47 +08:00

126 lines
4.3 KiB
C++

/* Copyright (c) 2019-2025, Arm Limited and Contributors
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 the "License";
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include "common/helpers.h"
#include "common/vk_common.h"
namespace vkb
{
class DescriptorSetLayout;
class DescriptorPool;
namespace core
{
template <vkb::BindingType bindingType>
class Device;
using DeviceC = Device<vkb::BindingType::C>;
} // namespace core
/**
* @brief A descriptor set handle allocated from a \ref DescriptorPool.
* Destroying the handle has no effect, as the pool manages the lifecycle of its descriptor sets.
*
* Keeps track of what bindings were written to prevent a double write.
*/
class DescriptorSet
{
public:
/**
* @brief Constructs a descriptor set from buffer infos and image infos
* Implicitly calls prepare()
* @param device A valid Vulkan device
* @param descriptor_set_layout The Vulkan descriptor set layout this descriptor set has
* @param descriptor_pool The Vulkan descriptor pool the descriptor set is allocated from
* @param buffer_infos The descriptors that describe buffer data
* @param image_infos The descriptors that describe image data
*/
DescriptorSet(vkb::core::DeviceC &device,
const DescriptorSetLayout &descriptor_set_layout,
DescriptorPool &descriptor_pool,
const BindingMap<VkDescriptorBufferInfo> &buffer_infos = {},
const BindingMap<VkDescriptorImageInfo> &image_infos = {});
DescriptorSet(const DescriptorSet &) = delete;
DescriptorSet(DescriptorSet &&other);
// The descriptor set handle is managed by the pool, and will be destroyed when the pool is reset
~DescriptorSet() = default;
DescriptorSet &operator=(const DescriptorSet &) = delete;
DescriptorSet &operator=(DescriptorSet &&) = delete;
/**
* @brief Resets the DescriptorSet state
* Optionally prepares a new set of buffer infos and/or image infos
* @param new_buffer_infos A map of buffer descriptors and their respective bindings
* @param new_image_infos A map of image descriptors and their respective bindings
*/
void reset(const BindingMap<VkDescriptorBufferInfo> &new_buffer_infos = {},
const BindingMap<VkDescriptorImageInfo> &new_image_infos = {});
/**
* @brief Updates the contents of the DescriptorSet by performing the write operations
* @param bindings_to_update If empty. we update all bindings. Otherwise, only write the specified bindings if they haven't already been written
*/
void update(const std::vector<uint32_t> &bindings_to_update = {});
/**
* @brief Applies pending write operations without updating the state
*/
void apply_writes() const;
const DescriptorSetLayout &get_layout() const;
VkDescriptorSet get_handle() const;
BindingMap<VkDescriptorBufferInfo> &get_buffer_infos();
BindingMap<VkDescriptorImageInfo> &get_image_infos();
protected:
/**
* @brief Prepares the descriptor set to have its contents updated by loading a vector of write operations
* Cannot be called twice during the lifetime of a DescriptorSet
*/
void prepare();
private:
vkb::core::DeviceC &device;
const DescriptorSetLayout &descriptor_set_layout;
DescriptorPool &descriptor_pool;
BindingMap<VkDescriptorBufferInfo> buffer_infos;
BindingMap<VkDescriptorImageInfo> image_infos;
VkDescriptorSet handle{VK_NULL_HANDLE};
// The list of write operations for the descriptor set
std::vector<VkWriteDescriptorSet> write_descriptor_sets;
// The bindings of the write descriptors that have had vkUpdateDescriptorSets since the last call to update().
// Each binding number is mapped to a hash of the binding description that it will be updated to.
std::unordered_map<uint32_t, size_t> updated_bindings;
};
} // namespace vkb