PipelineLayoutVk.h#

The Pipeline Layout class.

Includes#

  • PVRVk/DeviceVk.h

  • array

Included By#

Namespaces#

Classes#

Source Code#

#pragma once
#include "PVRVk/DeviceVk.h"
#include <array>

namespace pvrvk {
struct PipelineLayoutCreateInfo
{
    PipelineLayoutCreateInfo& addDescSetLayout(const DescriptorSetLayout& descLayout)
    {
        assert(size < static_cast<uint32_t>(FrameworkCaps::MaxDescriptorSetBindings) && "PipelineLayoutCreateInfo: Descriptor Set index cannot be 4 or greater");
        _descLayout[size++] = descLayout;
        return *this;
    }

    PipelineLayoutCreateInfo& setDescSetLayout(uint32_t index, const DescriptorSetLayout& descLayout)
    {
#ifdef DEBUG
        if (index >= static_cast<uint32_t>(FrameworkCaps::MaxDescriptorSetBindings))
        { assert(index < static_cast<uint32_t>(FrameworkCaps::MaxDescriptorSetBindings) && "PipelineLayoutCreateInfo: Descriptor Set index cannot be 4 or greater"); }
#endif
        if (index >= static_cast<uint32_t>(size)) { size = static_cast<uint8_t>(index) + 1u; }
        _descLayout[index] = descLayout;
        return *this;
    }

    uint32_t getNumDescriptorSetLayouts() const { return size; }

    const DescriptorSetLayout& getDescriptorSetLayout(uint32_t index) const
    {
#ifdef DEBUG
        if (index >= size) { assert(false && "Invalid DescriptorSetLayout Index"); }
#endif
        return _descLayout[index];
    }

    void clear()
    {
        for (size_t i = 0; i < size; ++i) { _descLayout[i].reset(); }
        size = 0;
    }

    const std::array<DescriptorSetLayout, FrameworkCaps::MaxDescriptorSetBindings>& getDescriptorSetLayouts() const { return _descLayout; }

    bool operator==(const PipelineLayoutCreateInfo& rhs) const
    {
        if (size != rhs.size) { return false; }
        for (size_t i = 0; i < size; ++i)
        {
            if (_descLayout[i] != rhs._descLayout[i]) { return false; }
        }
        return true;
    }

    void addPushConstantRange(const PushConstantRange& pushConstantRange)
    {
        if (pushConstantRange.getSize() == 0) { assert(false && "Push constant range size must not be be 0"); }

        _pushConstantRange.push_back(pushConstantRange);
    }

    void setPushConstantRange(uint32_t index, const PushConstantRange& pushConstantRange)
    {
        if (pushConstantRange.getSize() == 0) { assert(false && "Push constant range size must not be be 0"); }

        if (index >= _pushConstantRange.size()) { _pushConstantRange.resize(index + 1); }
        _pushConstantRange[index] = pushConstantRange;
    }

    const PushConstantRange& getPushConstantRange(uint32_t index) const { return _pushConstantRange.at(index); }

    uint32_t getNumPushConstantRanges() const { return static_cast<uint32_t>(_pushConstantRange.size()); }

    PipelineLayoutCreateInfo() : size(0) {}

private:
    bool isValidPushConstantRange(uint32_t index) { return _pushConstantRange[index].getSize() != 0; }
    friend class ::pvrvk::impl::PipelineLayout_;
    friend class ::pvrvk::impl::GraphicsPipeline_;
    std::array<DescriptorSetLayout, FrameworkCaps::MaxDescriptorSetBindings> _descLayout;
    uint8_t size;
    std::vector<PushConstantRange> _pushConstantRange;
};

namespace impl {
class PipelineLayout_ : public PVRVkDeviceObjectBase<VkPipelineLayout, ObjectType::e_PIPELINE_LAYOUT>, public DeviceObjectDebugUtils<PipelineLayout_>
{
private:
    friend class Device_;

    class make_shared_enabler
    {
    protected:
        make_shared_enabler() {}
        friend class PipelineLayout_;
    };

    static PipelineLayout constructShared(const DeviceWeakPtr& device, const PipelineLayoutCreateInfo& createInfo)
    {
        return std::make_shared<PipelineLayout_>(make_shared_enabler{}, device, createInfo);
    }

    PipelineLayoutCreateInfo _createInfo;

public:
    DECLARE_NO_COPY_SEMANTICS(PipelineLayout_)
    ~PipelineLayout_()
    {
        if (getVkHandle() != VK_NULL_HANDLE)
        {
            if (!_device.expired())
            {
                getDevice()->getVkBindings().vkDestroyPipelineLayout(getDevice()->getVkHandle(), getVkHandle(), nullptr);
                _vkHandle = VK_NULL_HANDLE;
            }
            else
            {
                reportDestroyedAfterDevice();
            }
        }
    }

    PipelineLayout_(make_shared_enabler, const DeviceWeakPtr& device, const PipelineLayoutCreateInfo& createInfo);

    const DescriptorSetLayout& getDescriptorSetLayout(uint32_t index) const
    {
        assert(index < _createInfo.size && "Invalid Index");
        return _createInfo._descLayout[index];
    }

    const DescriptorSetLayoutSet& getDescriptorSetLayouts() const { return _createInfo._descLayout; }

    uint32_t getNumDescriptorSetLayouts() const { return _createInfo.size; }

    const PipelineLayoutCreateInfo& getCreateInfo() const { return _createInfo; }
};
} // namespace impl
} // namespace pvrvk