KhronosGroup / Vulkan-Hpp

Open-Source Vulkan C++ API
Apache License 2.0
3.13k stars 307 forks source link

Feature request: appending to a StructureChain #1880

Closed litherum closed 4 months ago

litherum commented 5 months ago

There are quite a few chained structures in Vulkan which change behavior by their mere presence. Applications may want to provide these in some runtime situations but not others. However, the list of types in a StructureChain must be listed at compile-time, which makes it difficult to handle this kind of situation. (It's certainly possible to solve this by dropping down to C style and manually set pNext pointers, but this defeats the type-checking benefit of StructureChain.)

It would be useful if there was something that could take in an existing StructureChain, and append a new member to it. So, a client could do something like:

auto continuation = [&](const auto& structureChain) {
    return device.createSomething(structure.get<vk::BaseType>(structureChain));
}

auto structureChain = vk::StructureChain<vk::BaseType>();
// populate the base...
if (condition) {
    vk::ExtraType extra;
    // populate the extra...
    return continuation(appendToStructureChain(std::move(structureChain), std::move(extra)));
} else {
    return continuation(std::move(structureChain));
}
asuessenbach commented 5 months ago

As the vk::StructureChain is a compile-time thing, appending something to that would mean to create a new chain with that additional element and copy everything over. Sounds pretty expensive. But you might be able to do what you want with the functions vk::StructureChain::unlink and vk::StructureChain::relink. They modify the actual chaining of the vk::StructureChain at runtime, but don't really remove/add memory from/to the chain.

litherum commented 5 months ago

Right, I can make my own function to do what I want (in fact, I already did). It just might be something that others would find valuable, though, and might be a candidate to add to the public header itself.

asuessenbach commented 5 months ago

Using link/unlink, your sample code could look like this:

auto structureChain = vk::StructureChain<vk::BaseType, vk::ExtraType>();
// populate the base...
structureChain.assign<vk::BaseType>({...});
if (condition) {
    // populate the extra...
    structureChain.assign<vk::ExtraType>({...});
} else {
    // unlink the extra
    structureChain.unlink<vk::ExtraType>();
}
return device.createSomething(structureChain.get<vk::BaseType>());
asuessenbach commented 4 months ago

Closing this, assuming it's resolved.