Magnum::Vk::DescriptorSet class new in Git master

Descriptor set.

Wraps a VkDescriptorSet. A descriptor set is allocated from a DescriptorPool for a particular DescriptorSetLayout and specifies what descriptors (such as uniform buffers or samplers) are bound to shaders.

Descriptor set allocation

Given a DescriptorSetLayout and a compatible DescriptorPool with enough free slots, asingle descriptor set for given layout can be allocated with DescriptorPool::allocate():

Vk::DescriptorSetLayout layout{};
Vk::DescriptorPool pool{};

Vk::DescriptorSet set = pool.allocate(layout);

When allocating more than what the pool has, the DescriptorPool::allocate() function aborts with an error message. In cases where the application is very dynamic and cannot predict that a pools is large enough, you can use DescriptorPool::tryAllocate() instead and handle the failure gracefully — for example by recycling unused sets or by allocating from a different pool:

Containers::Optional<Vk::DescriptorSet> set = pool.tryAllocate(layout);

/* Oops, the pool is full (or fragmented). Hope the plan B doesn't fail too. */
if(!set) set = overflowPool.allocate(layout);

Freeing descriptor sets

By default, the DescriptorSet destructor is a no-op and descriptor sets are all freed together on a call to DescriptorPool::reset(). At that point all existing DescriptorSet instances become invalid. Alternatively, the pool can be created with DescriptorPoolCreateInfo::Flag::FreeDescriptorSet, which then makes a DescriptorSet free itself on destruction, allowing more descriptor sets to be allocated without resetting the whole pool. Using this flag however can cause allocation to fail also due to pool fragmentation, not just when exhausing all available resources:

Vk::DescriptorPool pool{device, Vk::DescriptorPoolCreateInfo{, {
    
}, Vk::DescriptorPoolCreateInfo::Flag::FreeDescriptorSet}};

{
    Vk::DescriptorSet set = pool.allocate(layout);

    // the set gets automatically freed at the end of scope
}

Variable descriptor count allocation

If the descriptor set layout contains a descriptor with variable count (there has to be at most one and it has to be the last binding), a concrete count is specified in the call to DescriptorPool::allocate(VkDescriptorSetLayout, UnsignedInt). Here the fragment shader can access up to 8 sampled images and we're allocating four:

Vk::Device device{instance, Vk::DeviceCreateInfo{}
    
    .addEnabledExtensions<Vk::Extensions::EXT::descriptor_indexing>()
    .setEnabledFeatures(
        Vk::DeviceFeature::DescriptorBindingVariableDescriptorCount|
        
    )
};

Vk::DescriptorSetLayout layout{device, Vk::DescriptorSetLayoutCreateInfo{
    {{, Vk::DescriptorType::SampledImage, 8,
      Vk::ShaderStage::Fragment,
      Vk::DescriptorSetLayoutBinding::Flag::VariableDescriptorCount}},
    
}};

Vk::DescriptorSet set = pool.allocate(layout, 4);

Public static functions

static auto wrap(Device& device, VkDescriptorPool pool, VkDescriptorSet handle, HandleFlags flags = {}) -> DescriptorSet
Wrap existing Vulkan handle.

Constructors, destructors, conversion operators

DescriptorSet(NoCreateT) explicit
Construct without creating the fence.
DescriptorSet(const DescriptorSet&) deleted
Copying is not allowed.
DescriptorSet(DescriptorSet&& other) noexcept
Move constructor.
~DescriptorSet()
Destructor.
operator VkDescriptorSet()

Public functions

auto operator=(const DescriptorSet&) -> DescriptorSet& deleted
Copying is not allowed.
auto operator=(DescriptorSet&& other) -> DescriptorSet& noexcept
Move assignment.
auto handle() -> VkDescriptorSet
Underlying VkDescriptorSet handle.
auto handleFlags() const -> HandleFlags
Handle flags.
auto release() -> VkDescriptorSet
Release the underlying Vulkan descriptor set.

Function documentation

static DescriptorSet Magnum::Vk::DescriptorSet::wrap(Device& device, VkDescriptorPool pool, VkDescriptorSet handle, HandleFlags flags = {})

Wrap existing Vulkan handle.

Parameters
device Vulkan device the descriptor pool is created on
pool Vulkan descriptor pool the set is allocated from
handle The VkDescriptorSet handle
flags Handle flags

The handle is expected to be originating from device. The Vulkan descriptor set is by default not freed on destruction — if the handle comes from a pool with DescriptorPoolCreateInfo::Flag::FreeDescriptorSet set and you want it to be freed on destruction, pass HandleFlag::DestroyOnDestruction to flags.

Magnum::Vk::DescriptorSet::DescriptorSet(NoCreateT) explicit

Construct without creating the fence.

The constructed instance is equivalent to moved-from state. Useful in cases where you will overwrite the instance later anyway. Move another object over it to make it useful.

Magnum::Vk::DescriptorSet::~DescriptorSet()

Destructor.

Frees associated VkDescriptorSet handle if it was allocated from a pool with DescriptorPoolCreateInfo::Flag::FreeDescriptorSet set or if it was created using wrap() with HandleFlag::DestroyOnDestruction specified. Otherwise does nothing.

Magnum::Vk::DescriptorSet::operator VkDescriptorSet()

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

VkDescriptorSet Magnum::Vk::DescriptorSet::release()

Release the underlying Vulkan descriptor set.

Releases ownership of the Vulkan descriptor set and returns its handle so vkFreeDescriptorSets() is not called on destruction. The internal state is then equivalent to moved-from state.