mirror of
https://github.com/PancakeTAS/lsfg-vk.git
synced 2025-10-30 07:01:10 +00:00
core descriptor pool/set objects
This commit is contained in:
parent
013950596c
commit
d3a903524a
4 changed files with 195 additions and 0 deletions
49
include/core/descriptorpool.hpp
Normal file
49
include/core/descriptorpool.hpp
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
#ifndef DESCRIPTORPOOL_HPP
|
||||
#define DESCRIPTORPOOL_HPP
|
||||
|
||||
#include "device.hpp"
|
||||
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace Vulkan::Core {
|
||||
|
||||
///
|
||||
/// C++ wrapper class for a Vulkan descriptor pool.
|
||||
///
|
||||
/// This class manages the lifetime of a Vulkan descriptor pool.
|
||||
///
|
||||
class DescriptorPool {
|
||||
public:
|
||||
///
|
||||
/// Create the descriptor pool.
|
||||
///
|
||||
/// @param device Vulkan device
|
||||
///
|
||||
/// @throws std::invalid_argument if the device is invalid.
|
||||
/// @throws ls::vulkan_error if object creation fails.
|
||||
///
|
||||
DescriptorPool(const Device& device);
|
||||
|
||||
/// Get the Vulkan handle.
|
||||
[[nodiscard]] auto handle() const { return *this->descriptorPool; }
|
||||
|
||||
/// Check whether the object is valid.
|
||||
[[nodiscard]] bool isValid() const { return static_cast<bool>(this->descriptorPool); }
|
||||
/// if (obj) operator. Checks if the object is valid.
|
||||
explicit operator bool() const { return this->isValid(); }
|
||||
|
||||
/// Trivially copyable, moveable and destructible
|
||||
DescriptorPool(const DescriptorPool&) noexcept = default;
|
||||
DescriptorPool& operator=(const DescriptorPool&) noexcept = default;
|
||||
DescriptorPool(DescriptorPool&&) noexcept = default;
|
||||
DescriptorPool& operator=(DescriptorPool&&) noexcept = default;
|
||||
~DescriptorPool() = default;
|
||||
private:
|
||||
std::shared_ptr<VkDescriptorPool> descriptorPool;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // DESCRIPTORPOOL_HPP
|
||||
66
include/core/descriptorset.hpp
Normal file
66
include/core/descriptorset.hpp
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
#ifndef DESCRIPTORSET_HPP
|
||||
#define DESCRIPTORSET_HPP
|
||||
|
||||
#include "core/commandbuffer.hpp"
|
||||
#include "core/descriptorpool.hpp"
|
||||
#include "core/pipeline.hpp"
|
||||
#include "core/shadermodule.hpp"
|
||||
#include "device.hpp"
|
||||
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace Vulkan::Core {
|
||||
|
||||
///
|
||||
/// C++ wrapper class for a Vulkan descriptor set.
|
||||
///
|
||||
/// This class manages the lifetime of a Vulkan descriptor set.
|
||||
///
|
||||
class DescriptorSet {
|
||||
public:
|
||||
///
|
||||
/// Create the descriptor set.
|
||||
///
|
||||
/// @param device Vulkan device
|
||||
/// @param pool Descriptor pool to allocate from
|
||||
/// @param shaderModule Shader module to use for the descriptor set
|
||||
///
|
||||
/// @throws std::invalid_argument if the device or pool is invalid.
|
||||
/// @throws ls::vulkan_error if object creation fails.
|
||||
///
|
||||
DescriptorSet(const Device& device,
|
||||
DescriptorPool pool, const ShaderModule& shaderModule);
|
||||
|
||||
///
|
||||
/// Bind a descriptor set to a command buffer.
|
||||
///
|
||||
/// @param commandBuffer Command buffer to bind the descriptor set to.
|
||||
/// @param pipeline Pipeline to bind the descriptor set to.
|
||||
///
|
||||
/// @throws std::invalid_argument if the command buffer is invalid.
|
||||
///
|
||||
void bind(const CommandBuffer& commandBuffer, const Pipeline& pipeline) const;
|
||||
|
||||
/// Get the Vulkan handle.
|
||||
[[nodiscard]] auto handle() const { return *this->descriptorSet; }
|
||||
|
||||
/// Check whether the object is valid.
|
||||
[[nodiscard]] bool isValid() const { return static_cast<bool>(this->descriptorSet); }
|
||||
/// if (obj) operator. Checks if the object is valid.
|
||||
explicit operator bool() const { return this->isValid(); }
|
||||
|
||||
/// Trivially copyable, moveable and destructible
|
||||
DescriptorSet(const DescriptorSet&) noexcept = default;
|
||||
DescriptorSet& operator=(const DescriptorSet&) noexcept = default;
|
||||
DescriptorSet(DescriptorSet&&) noexcept = default;
|
||||
DescriptorSet& operator=(DescriptorSet&&) noexcept = default;
|
||||
~DescriptorSet() = default;
|
||||
private:
|
||||
std::shared_ptr<VkDescriptorSet> descriptorSet;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // DESCRIPTORSET_HPP
|
||||
37
src/core/descriptorpool.cpp
Normal file
37
src/core/descriptorpool.cpp
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
#include "core/descriptorpool.hpp"
|
||||
#include "utils/exceptions.hpp"
|
||||
|
||||
#include <array>
|
||||
|
||||
using namespace Vulkan::Core;
|
||||
|
||||
DescriptorPool::DescriptorPool(const Device& device) {
|
||||
if (!device)
|
||||
throw std::invalid_argument("Invalid Vulkan device");
|
||||
|
||||
// create descriptor pool
|
||||
const std::array<VkDescriptorPoolSize, 4> pools{{ // arbitrary limits
|
||||
{ .type = VK_DESCRIPTOR_TYPE_SAMPLER, .descriptorCount = 4096 },
|
||||
{ .type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, .descriptorCount = 4096 },
|
||||
{ .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, .descriptorCount = 4096 },
|
||||
{ .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, .descriptorCount = 4096 }
|
||||
}};
|
||||
const VkDescriptorPoolCreateInfo desc{
|
||||
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
|
||||
.maxSets = 16384, // arbitrary limit
|
||||
.poolSizeCount = static_cast<uint32_t>(pools.size()),
|
||||
.pPoolSizes = pools.data()
|
||||
};
|
||||
VkDescriptorPool poolHandle{};
|
||||
auto res = vkCreateDescriptorPool(device.handle(), &desc, nullptr, &poolHandle);
|
||||
if (res != VK_SUCCESS || poolHandle == VK_NULL_HANDLE)
|
||||
throw ls::vulkan_error(res, "Unable to create descriptor pool");
|
||||
|
||||
/// store pool in shared ptr
|
||||
this->descriptorPool = std::shared_ptr<VkDescriptorPool>(
|
||||
new VkDescriptorPool(poolHandle),
|
||||
[dev = device.handle()](VkDescriptorPool* poolHandle) {
|
||||
vkDestroyDescriptorPool(dev, *poolHandle, nullptr);
|
||||
}
|
||||
);
|
||||
}
|
||||
43
src/core/descriptorset.cpp
Normal file
43
src/core/descriptorset.cpp
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
#include "core/descriptorset.hpp"
|
||||
#include "utils/exceptions.hpp"
|
||||
|
||||
using namespace Vulkan::Core;
|
||||
|
||||
DescriptorSet::DescriptorSet(const Device& device,
|
||||
DescriptorPool pool, const ShaderModule& shaderModule) {
|
||||
if (!device || !pool)
|
||||
throw std::invalid_argument("Invalid Vulkan device");
|
||||
|
||||
// create descriptor set
|
||||
VkDescriptorSetLayout layout = shaderModule.getDescriptorSetLayout();
|
||||
const VkDescriptorSetAllocateInfo desc{
|
||||
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
|
||||
.descriptorPool = pool.handle(),
|
||||
.descriptorSetCount = 1,
|
||||
.pSetLayouts = &layout
|
||||
};
|
||||
VkDescriptorSet descriptorSetHandle{};
|
||||
auto res = vkAllocateDescriptorSets(device.handle(), &desc, &descriptorSetHandle);
|
||||
if (res != VK_SUCCESS || descriptorSetHandle == VK_NULL_HANDLE)
|
||||
throw ls::vulkan_error(res, "Unable to allocate descriptor set");
|
||||
|
||||
/// store descriptor set in shared ptr
|
||||
this->descriptorSet = std::shared_ptr<VkDescriptorSet>(
|
||||
new VkDescriptorSet(descriptorSetHandle),
|
||||
[dev = device.handle(), pool = std::move(pool)](VkDescriptorSet* setHandle) {
|
||||
vkFreeDescriptorSets(dev, pool.handle(), 1, setHandle);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void DescriptorSet::bind(const CommandBuffer& commandBuffer, const Pipeline& pipeline) const {
|
||||
if (!commandBuffer)
|
||||
throw std::invalid_argument("Invalid command buffer");
|
||||
|
||||
// bind descriptor set
|
||||
VkDescriptorSet descriptorSetHandle = this->handle();
|
||||
vkCmdBindDescriptorSets(commandBuffer.handle(),
|
||||
VK_PIPELINE_BIND_POINT_COMPUTE, pipeline.getLayout(),
|
||||
0, 1, &descriptorSetHandle,
|
||||
0, nullptr);
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue