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

Shader set.

A collection of Shader instances together with populated VkPipelineShaderStageCreateInfo structures for use in a pipeline.

Usage

Based on whether the shader set is for a rasterization, compute or ray tracing pipeline, you'll call addShader() with all Shader stages that the pipeline needs. At the very least you need to specify what stage is the shader for and the entrypoint name — usually it'd be main(), but there can be also SPIR-V shader modules with multiple entry points, which is why this parameter is needed.

Vk::Shader vert{}, frag{};

using namespace Containers::Literals;

Vk::ShaderSet set;
set.addShader(Vk::ShaderStage::Vertex, vert, "main"_s)
   .addShader(Vk::ShaderStage::Fragment, frag, "main"_s);

Specialization constants

If the shader module exposes specialization constants, those can be specialized via an additional parameter, taking a list of ShaderSpecialization instances. The constant can be an integer, float or a boolean; constant IDs not present in the SPIR-V module are ignored.

set.addShader(Vk::ShaderStage::Fragment, frag, "main"_s, {
    {0, 3},
    {1, 0.25f},
    {2, false}
});

Shader ownership transfer

To create a self-contained shader set it's possible to move the Shader instances into the class using the addShader(ShaderStage, Shader&&, Containers::StringView, Containers::ArrayView<const ShaderSpecialization>) overload. If you have a multi-entrypoint shader, move only the last specified stage, for example:

Vk::Shader shader{};

Vk::ShaderSet set;
set.addShader(Vk::ShaderStage::Vertex, shader, "vert"_s)
   .addShader(Vk::ShaderStage::Fragment, std::move(shader), "frag"_s);

Constructors, destructors, conversion operators

ShaderSet() explicit
Constructor.
ShaderSet(const ShaderSet&) deleted
Copying is not allowed.
ShaderSet(ShaderSet&& other) noexcept
Move constructor.
~ShaderSet()
Destructor.

Public functions

auto operator=(const ShaderSet&) -> ShaderSet& deleted
Copying is not allowed.
auto operator=(ShaderSet&& other) -> ShaderSet& noexcept
Move assignment.
auto addShader(ShaderStage stage, VkShaderModule shader, Containers::StringView entrypoint, Containers::ArrayView<const ShaderSpecialization> specializations) -> ShaderSet&
Add a shader.
auto addShader(ShaderStage stage, VkShaderModule shader, Containers::StringView entrypoint, std::initializer_list<ShaderSpecialization> specializations = {}) -> ShaderSet&
auto addShader(ShaderStage stage, Shader&& shader, Containers::StringView entrypoint, Containers::ArrayView<const ShaderSpecialization> specializations) -> ShaderSet&
Add a shader and take over its ownership.
auto addShader(ShaderStage stage, Shader&& shader, Containers::StringView entrypoint, std::initializer_list<ShaderSpecialization> specializations = {}) -> ShaderSet&
auto stages() -> Containers::ArrayView<VkPipelineShaderStageCreateInfo>
Shader stages.
auto stages() const -> Containers::ArrayView<const VkPipelineShaderStageCreateInfo>

Function documentation

Magnum::Vk::ShaderSet::ShaderSet() explicit

Constructor.

Creates an empty shader set. At least one shader has to be present, call addShader() to add it.

Magnum::Vk::ShaderSet::~ShaderSet()

Destructor.

If any shaders were added using addShader(ShaderStage, Shader&&, Containers::StringView, Containers::ArrayView<const ShaderSpecialization>), their owned instances are destructed at this point.

ShaderSet& Magnum::Vk::ShaderSet::addShader(ShaderStage stage, VkShaderModule shader, Containers::StringView entrypoint, Containers::ArrayView<const ShaderSpecialization> specializations)

Add a shader.

Parameters
stage Shader stage
shader A Shader or a raw Vulkan shader handle
entrypoint Entrypoint name
specializations Specialization constant values
Returns Reference to self (for method chaining)

The function makes a copy of entrypoint if it's not global or null-terminated, use the Containers::Literals::operator""_s() literal to prevent that where possible.

The populated VkVkPipelineShaderStageCreateInfo is subsequently available through stages() for direct editing. The following fields are pre-filled in addition to sType, everything else is zero-filled:

  • stage
  • module to shader
  • pName to entrypoint
  • pSpecializationInfo, if specializations are non-empty
  • pSpecializationInfo->mapEntryCount, pSpecializationInfo->pMapEntries, pSpecializationInfo->pMapEntries[i].constantID, pSpecializationInfo->pMapEntries[i].offset, pSpecializationInfo->pMapEntries[i].size, pSpecializationInfo->dataSize and pSpecializationInfo->pData to processed and linearized contents of specializations

ShaderSet& Magnum::Vk::ShaderSet::addShader(ShaderStage stage, VkShaderModule shader, Containers::StringView entrypoint, std::initializer_list<ShaderSpecialization> specializations = {})

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

ShaderSet& Magnum::Vk::ShaderSet::addShader(ShaderStage stage, Shader&& shader, Containers::StringView entrypoint, Containers::ArrayView<const ShaderSpecialization> specializations)

Add a shader and take over its ownership.

Returns Reference to self (for method chaining)

Compared to addShader(ShaderStage, VkShaderModule, Containers::StringView, Containers::ArrayView<const ShaderSpecialization>) the shader instance ownership is transferred to the class and thus doesn't have to be managed separately.

ShaderSet& Magnum::Vk::ShaderSet::addShader(ShaderStage stage, Shader&& shader, Containers::StringView entrypoint, std::initializer_list<ShaderSpecialization> specializations = {})

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

Containers::ArrayView<VkPipelineShaderStageCreateInfo> Magnum::Vk::ShaderSet::stages()

Shader stages.

Exposes all data added with addShader() calls. If addShader() was not called yet, the returned view is empty.

Containers::ArrayView<const VkPipelineShaderStageCreateInfo> Magnum::Vk::ShaderSet::stages() const

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