Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • 119-graphicspipeline-refactoring
  • 129-projekte-und-assets-auslagern
  • 132-denoising-module
  • 143-ar-vr-support-via-openxr
  • 43-multi-threading
  • 91-compute-first-network
  • 95-arm64-raspberry-pi-4-support
  • develop
  • master
  • optimizations
  • 0.1.0
  • 0.2.0
12 results

Target

Select target project
  • vulkan2021/vkcv-framework
1 result
Select Git revision
  • 119-graphicspipeline-refactoring
  • 129-projekte-und-assets-auslagern
  • 132-denoising-module
  • 143-ar-vr-support-via-openxr
  • 43-multi-threading
  • 91-compute-first-network
  • 95-arm64-raspberry-pi-4-support
  • develop
  • master
  • optimizations
  • 0.1.0
  • 0.2.0
12 results
Show changes
Commits on Source (2)
Showing
with 288 additions and 112 deletions
......@@ -44,6 +44,14 @@ namespace vkcv
void init();
/**
* Destroys and deallocates buffer represented by a given
* buffer handle id.
*
* @param id Buffer handle id
*/
void destroyBufferById(uint64_t id);
public:
~BufferManager() noexcept;
......@@ -123,14 +131,6 @@ namespace vkcv
* @param handle Buffer handle
*/
void unmapBuffer(const BufferHandle& handle);
/**
* Destroys and deallocates buffer represented by a given
* buffer handle.
*
* @param handle Buffer handle
*/
void destroyBuffer(const BufferHandle& handle);
};
......
......@@ -21,6 +21,7 @@
#include "vkcv/DescriptorConfig.hpp"
#include "Sampler.hpp"
#include "DescriptorWrites.hpp"
#include "Event.hpp"
namespace vkcv
{
......@@ -43,8 +44,8 @@ namespace vkcv
std::vector<vk::Semaphore> signalSemaphores;
};
typedef std::function<void(const vk::CommandBuffer& cmdBuffer)> RecordCommandFunction;
typedef std::function<void(void)> FinishCommandFunction;
typedef typename event_function<const vk::CommandBuffer&>::type RecordCommandFunction;
typedef typename event_function<>::type FinishCommandFunction;
class Core final
{
......@@ -80,6 +81,8 @@ namespace vkcv
SyncResources m_SyncResources;
uint32_t m_currentSwapchainImageIndex;
std::vector<vk::Framebuffer> m_TemporaryFramebuffers;
ImageHandle m_DepthImage;
/**
* recreates the swapchain
......@@ -229,8 +232,8 @@ namespace vkcv
void renderMesh(
const PassHandle renderpassHandle,
const PipelineHandle pipelineHandle,
const int width,
const int height,
const uint32_t width,
const uint32_t height,
const size_t pushConstantSize,
const void* pushConstantData,
const std::vector<VertexBufferBinding> &vertexBufferBindings,
......
......@@ -7,31 +7,51 @@
#include <iostream>
#include "Event.hpp"
namespace vkcv
{
typedef typename event_function<uint64_t>::type HandleDestroyFunction;
class Handle {
friend std::ostream& operator << (std::ostream& out, const Handle& handle);
private:
uint64_t m_id;
uint64_t* m_rc;
HandleDestroyFunction m_destroy;
protected:
Handle();
explicit Handle(uint64_t id);
explicit Handle(uint64_t id, const HandleDestroyFunction& destroy = nullptr);
/**
* Returns the actual handle id of a handle.
*
* @return Handle id
*/
[[nodiscard]]
uint64_t getId() const;
/**
* Returns the reference counter of a handle
*
* @return Reference counter
*/
[[nodiscard]]
uint64_t getRC() const;
public:
virtual ~Handle() = default;
virtual ~Handle();
Handle(const Handle& other) = default;
Handle(Handle&& other) = default;
Handle(const Handle& other);
Handle(Handle&& other) noexcept;
Handle& operator=(const Handle& other) = default;
Handle& operator=(Handle&& other) = default;
Handle& operator=(const Handle& other);
Handle& operator=(Handle&& other) noexcept;
explicit operator bool() const;
bool operator!() const;
......
......@@ -39,12 +39,9 @@ namespace vkcv {
ImageManager* const m_manager;
const ImageHandle m_handle;
const vk::Format m_format;
const uint32_t m_width;
const uint32_t m_height;
const uint32_t m_depth;
vk::ImageLayout m_layout;
Image(ImageManager* manager, const ImageHandle& handle, vk::Format format, uint32_t width, uint32_t height, uint32_t depth);
Image(ImageManager* manager, const ImageHandle& handle, vk::Format format);
static Image create(ImageManager* manager, vk::Format format, uint32_t width, uint32_t height, uint32_t depth);
......
......@@ -23,7 +23,7 @@ namespace vkcv {
BufferManager::~BufferManager() noexcept {
for (uint64_t id = 0; id < m_buffers.size(); id++) {
destroyBuffer(BufferHandle(id));
destroyBufferById(id);
}
}
......@@ -119,7 +119,7 @@ namespace vkcv {
const uint64_t id = m_buffers.size();
m_buffers.push_back({ buffer, memory, size, nullptr, mappable });
return BufferHandle{ id };
return BufferHandle(id, [&](uint64_t id) { destroyBufferById(id); });
}
struct StagingStepInfo {
......@@ -315,9 +315,7 @@ namespace vkcv {
buffer.m_mapped = nullptr;
}
void BufferManager::destroyBuffer(const BufferHandle& handle) {
const uint64_t id = handle.getId();
void BufferManager::destroyBufferById(uint64_t id) {
if (id >= m_buffers.size()) {
return;
}
......
......@@ -176,8 +176,8 @@ namespace vkcv
void Core::renderMesh(
const PassHandle renderpassHandle,
const PipelineHandle pipelineHandle,
const int width,
const int height,
const uint32_t width,
const uint32_t height,
const size_t pushConstantSize,
const void *pushConstantData,
const std::vector<VertexBufferBinding>& vertexBufferBindings,
......@@ -194,12 +194,18 @@ namespace vkcv
const vk::RenderPass renderpass = m_PassManager->getVkPass(renderpassHandle);
const PassConfig passConfig = m_PassManager->getPassConfig(renderpassHandle);
ImageHandle depthImage;
const bool checkForDepthImage = (
(!m_DepthImage) ||
(width != m_ImageManager->getImageWidth(m_DepthImage)) ||
(height != m_ImageManager->getImageHeight(m_DepthImage))
);
for (const auto& attachment : passConfig.attachments) {
if (attachment.layout_final == AttachmentLayout::DEPTH_STENCIL_ATTACHMENT) {
depthImage = m_ImageManager->createImage(width, height, 1, attachment.format);
break;
if (checkForDepthImage) {
for (const auto &attachment : passConfig.attachments) {
if (attachment.layout_final == AttachmentLayout::DEPTH_STENCIL_ATTACHMENT) {
m_DepthImage = m_ImageManager->createImage(width, height, 1, attachment.format);
break;
}
}
}
......@@ -212,8 +218,8 @@ namespace vkcv
std::vector<vk::ImageView> attachments;
attachments.push_back(imageView);
if (depthImage) {
attachments.push_back(m_ImageManager->getVulkanImageView(depthImage));
if (m_DepthImage) {
attachments.push_back(m_ImageManager->getVulkanImageView(m_DepthImage));
}
const vk::Framebuffer framebuffer = createFramebuffer(
......@@ -273,9 +279,7 @@ namespace vkcv
cmdBuffer.pushConstants(pipelineLayout, vk::ShaderStageFlagBits::eAll, 0, pushConstantSize, pushConstantData);
cmdBuffer.drawIndexed(indexCount, 1, 0, 0, {});
cmdBuffer.endRenderPass();
}, [&]() {
m_ImageManager->destroyImage(depthImage);
});
}, nullptr);
}
void Core::endFrame() {
......
......@@ -8,7 +8,7 @@ namespace vkcv
descriptorSetLayouts{std::move(layouts)}
{}
DescriptorManager::DescriptorManager(vk::Device device) noexcept:
m_Device{ device }, m_NextResourceDescriptionID{ 0 }
m_Device{ device }
{
/**
* Allocate a set size for the initial pool, namely 1000 units of each descriptor type below.
......@@ -32,11 +32,10 @@ namespace vkcv
DescriptorManager::~DescriptorManager() noexcept
{
for(const auto &resource : m_ResourceDescriptions)
{
for(const auto &layout : resource.descriptorSetLayouts)
m_Device.destroyDescriptorSetLayout(layout);
for (uint64_t id = 0; id < m_ResourceDescriptions.size(); id++) {
destroyResourceDescriptionById(id);
}
m_Device.destroy(m_Pool);
}
......@@ -82,8 +81,9 @@ namespace vkcv
return ResourcesHandle();
};
const uint64_t id = m_ResourceDescriptions.size();
m_ResourceDescriptions.emplace_back(vk_sets, vk_setLayouts);
return ResourcesHandle(m_NextResourceDescriptionID++);
return ResourcesHandle(id, [&](uint64_t id) { destroyResourceDescriptionById(id); });
}
struct WriteDescriptorSetInfo {
......@@ -270,5 +270,19 @@ namespace vkcv
return vk::ShaderStageFlagBits::eAll;
}
}
void DescriptorManager::destroyResourceDescriptionById(uint64_t id) {
if (id >= m_ResourceDescriptions.size()) {
return;
}
auto& resourceDescription = m_ResourceDescriptions[id];
for(const auto &layout : resourceDescription.descriptorSetLayouts) {
m_Device.destroyDescriptorSetLayout(layout);
}
resourceDescription.descriptorSetLayouts.clear();
}
}
\ No newline at end of file
......@@ -58,8 +58,6 @@ namespace vkcv
* Contains all the resource descriptions that were requested by the user in calls of createResourceDescription.
*/
std::vector<ResourceDescription> m_ResourceDescriptions;
// Counter for the vector above
uint64_t m_NextResourceDescriptionID;
/**
* Converts the flags of the descriptor types from VulkanCV (vkcv) to Vulkan (vk).
......@@ -73,5 +71,8 @@ namespace vkcv
* @return vk flag of the ShaderStage
*/
static vk::ShaderStageFlagBits convertShaderStageFlag(ShaderStage stage);
void destroyResourceDescriptionById(uint64_t id);
};
}
\ No newline at end of file
......@@ -3,17 +3,75 @@
namespace vkcv {
Handle::Handle() :
m_id(UINT64_MAX)
m_id(UINT64_MAX), m_rc(nullptr), m_destroy(nullptr)
{}
Handle::Handle(uint64_t id) :
m_id(id)
Handle::Handle(uint64_t id, const HandleDestroyFunction& destroy) :
m_id(id), m_rc(new uint64_t(1)), m_destroy(destroy)
{}
Handle::~Handle() {
if ((m_rc) && (--(*m_rc) == 0)) {
if (m_destroy) {
m_destroy(m_id);
}
delete m_rc;
}
}
Handle::Handle(const Handle &other) :
m_id(other.m_id),
m_rc(other.m_rc),
m_destroy(other.m_destroy)
{
if (m_rc) {
++(*m_rc);
}
}
Handle::Handle(Handle &&other) noexcept :
m_id(other.m_id),
m_rc(other.m_rc),
m_destroy(other.m_destroy)
{
other.m_rc = nullptr;
}
Handle &Handle::operator=(const Handle &other) {
if (&other == this) {
return *this;
}
m_id = other.m_id;
m_rc = other.m_rc;
m_destroy = other.m_destroy;
if (m_rc) {
++(*m_rc);
}
return *this;
}
Handle &Handle::operator=(Handle &&other) noexcept {
m_id = other.m_id;
m_rc = other.m_rc;
m_destroy = other.m_destroy;
other.m_rc = nullptr;
return *this;
}
uint64_t Handle::getId() const {
return m_id;
}
uint64_t Handle::getRC() const {
return m_rc? *m_rc : 0;
}
Handle::operator bool() const {
return (m_id < UINT64_MAX);
}
......@@ -24,7 +82,7 @@ namespace vkcv {
std::ostream& operator << (std::ostream& out, const Handle& handle) {
if (handle) {
return out << "[Handle: " << handle.getId() << "]";
return out << "[Handle: " << handle.getId() << ":" << handle.getRC() << "]";
} else {
return out << "[Handle: none]";
}
......
......@@ -10,7 +10,7 @@ namespace vkcv{
Image Image::create(ImageManager* manager, vk::Format format, uint32_t width, uint32_t height, uint32_t depth)
{
return Image(manager, manager->createImage(width, height, depth, format), format, width, height, depth);
return Image(manager, manager->createImage(width, height, depth, format), format);
}
vk::Format Image::getFormat() const {
......@@ -18,15 +18,15 @@ namespace vkcv{
}
uint32_t Image::getWidth() const {
return m_width;
return m_manager->getImageWidth(m_handle);
}
uint32_t Image::getHeight() const {
return m_height;
return m_manager->getImageHeight(m_handle);
}
uint32_t Image::getDepth() const {
return m_depth;
return m_manager->getImageDepth(m_handle);
}
vk::ImageLayout Image::getLayout() const {
......@@ -47,14 +47,10 @@ namespace vkcv{
m_manager->fillImage(m_handle, data, size);
}
Image::Image(ImageManager* manager, const ImageHandle& handle,
vk::Format format, uint32_t width, uint32_t height, uint32_t depth) :
Image::Image(ImageManager* manager, const ImageHandle& handle, vk::Format format) :
m_manager(manager),
m_handle(handle),
m_format(format),
m_width(width),
m_height(height),
m_depth(depth),
m_layout(vk::ImageLayout::eUndefined)
{
}
......
......@@ -43,7 +43,7 @@ namespace vkcv {
ImageManager::~ImageManager() noexcept {
for (uint64_t id = 0; id < m_images.size(); id++) {
destroyImage(ImageHandle(id));
destroyImageById(id);
}
}
......@@ -167,7 +167,7 @@ namespace vkcv {
const uint64_t id = m_images.size();
m_images.push_back({ image, memory, view, width, height, depth, format, arrayLayers, mipLevels });
return ImageHandle(id);
return ImageHandle(id, [&](uint64_t id) { destroyImageById(id); });
}
vk::Image ImageManager::getVulkanImage(const ImageHandle &handle) const {
......@@ -359,16 +359,48 @@ namespace vkcv {
vk::ImageLayout::eTransferDstOptimal,
vk::ImageLayout::eShaderReadOnlyOptimal
);
m_bufferManager.destroyBuffer(bufferHandle);
}
);
}
void ImageManager::destroyImage(const ImageHandle& handle)
{
uint32_t ImageManager::getImageWidth(const ImageHandle &handle) const {
const uint64_t id = handle.getId();
if (id >= m_images.size()) {
return 0;
}
auto& image = m_images[id];
return image.m_width;
}
uint32_t ImageManager::getImageHeight(const ImageHandle &handle) const {
const uint64_t id = handle.getId();
if (id >= m_images.size()) {
return 0;
}
auto& image = m_images[id];
return image.m_height;
}
uint32_t ImageManager::getImageDepth(const ImageHandle &handle) const {
const uint64_t id = handle.getId();
if (id >= m_images.size()) {
return 0;
}
auto& image = m_images[id];
return image.m_depth;
}
void ImageManager::destroyImageById(uint64_t id)
{
if (id >= m_images.size()) {
return;
}
......
......@@ -36,6 +36,14 @@ namespace vkcv {
ImageManager(BufferManager& bufferManager) noexcept;
/**
* Destroys and deallocates image represented by a given
* image handle id.
*
* @param id Image handle id
*/
void destroyImageById(uint64_t id);
public:
~ImageManager() noexcept;
ImageManager(ImageManager&& other) = delete;
......@@ -57,14 +65,15 @@ namespace vkcv {
void switchImageLayout(const ImageHandle& handle, vk::ImageLayout oldLayout, vk::ImageLayout newLayout);
void fillImage(const ImageHandle& handle, void* data, size_t size);
/**
* Destroys and deallocates image represented by a given
* buffer handle.
*
* @param handle Image handle
*/
void destroyImage(const ImageHandle& handle);
[[nodiscard]]
uint32_t getImageWidth(const ImageHandle& handle) const;
[[nodiscard]]
uint32_t getImageHeight(const ImageHandle& handle) const;
[[nodiscard]]
uint32_t getImageDepth(const ImageHandle& handle) const;
};
}
\ No newline at end of file
......@@ -49,17 +49,14 @@ namespace vkcv
PassManager::PassManager(vk::Device device) noexcept :
m_Device{device},
m_Passes{},
m_NextPassId(0)
m_Passes{}
{}
PassManager::~PassManager() noexcept
{
for(const auto &pass : m_Passes)
m_Device.destroy(pass.m_Handle);
m_Passes.clear();
m_NextPassId = 0;
for (uint64_t id = 0; id < m_Passes.size(); id++) {
destroyPassById(id);
}
}
PassHandle PassManager::createPass(const PassConfig &config)
......@@ -130,8 +127,9 @@ namespace vkcv
vk::RenderPass renderPass = m_Device.createRenderPass(passInfo);
const uint64_t id = m_Passes.size();
m_Passes.push_back({ renderPass, config });
return PassHandle(m_NextPassId++);
return PassHandle(id, [&](uint64_t id) { destroyPassById(id); });
}
vk::RenderPass PassManager::getVkPass(const PassHandle &handle) const
......@@ -160,4 +158,17 @@ namespace vkcv
return pass.m_Config;
}
void PassManager::destroyPassById(uint64_t id) {
if (id >= m_Passes.size()) {
return;
}
auto& pass = m_Passes[id];
if (pass.m_Handle) {
m_Device.destroy(pass.m_Handle);
pass.m_Handle = nullptr;
}
}
}
......@@ -17,7 +17,9 @@ namespace vkcv
vk::Device m_Device;
std::vector<Pass> m_Passes;
uint64_t m_NextPassId;
void destroyPassById(uint64_t id);
public:
PassManager() = delete; // no default ctor
explicit PassManager(vk::Device device) noexcept; // ctor
......
......@@ -5,22 +5,14 @@ namespace vkcv
PipelineManager::PipelineManager(vk::Device device) noexcept :
m_Device{device},
m_Pipelines{},
m_PipelineLayouts{},
m_NextPipelineId{0}
m_Pipelines{}
{}
PipelineManager::~PipelineManager() noexcept
{
for(const auto &pipeline: m_Pipelines)
m_Device.destroy(pipeline);
for(const auto &layout : m_PipelineLayouts)
m_Device.destroy(layout);
m_Pipelines.clear();
m_PipelineLayouts.clear();
m_NextPipelineId = 0;
for (uint64_t id = 0; id < m_Pipelines.size(); id++) {
destroyPipelineById(id);
}
}
// currently assuming default 32 bit formats, no lower precision or normalized variants supported
......@@ -252,19 +244,54 @@ namespace vkcv
m_Device.destroy(vertexModule);
m_Device.destroy(fragmentModule);
m_Pipelines.push_back(vkPipeline);
m_PipelineLayouts.push_back(vkPipelineLayout);
return PipelineHandle(m_NextPipelineId++);
const uint64_t id = m_Pipelines.size();
m_Pipelines.push_back({ vkPipeline, vkPipelineLayout });
return PipelineHandle(id, [&](uint64_t id) { destroyPipelineById(id); });
}
vk::Pipeline PipelineManager::getVkPipeline(const PipelineHandle &handle) const
{
return m_Pipelines.at(handle.getId());
const uint64_t id = handle.getId();
if (id >= m_Pipelines.size()) {
return nullptr;
}
auto& pipeline = m_Pipelines[id];
return pipeline.m_handle;
}
vk::PipelineLayout PipelineManager::getVkPipelineLayout(const PipelineHandle &handle) const
{
return m_PipelineLayouts.at(handle.getId());
const uint64_t id = handle.getId();
if (id >= m_Pipelines.size()) {
return nullptr;
}
auto& pipeline = m_Pipelines[id];
return pipeline.m_layout;
}
void PipelineManager::destroyPipelineById(uint64_t id) {
if (id >= m_Pipelines.size()) {
return;
}
auto& pipeline = m_Pipelines[id];
if (pipeline.m_handle) {
m_Device.destroy(pipeline.m_handle);
pipeline.m_handle = nullptr;
}
if (pipeline.m_layout) {
m_Device.destroy(pipeline.m_layout);
pipeline.m_layout = nullptr;
}
}
}
\ No newline at end of file
......@@ -11,10 +11,16 @@ namespace vkcv
class PipelineManager
{
private:
struct Pipeline {
vk::Pipeline m_handle;
vk::PipelineLayout m_layout;
};
vk::Device m_Device;
std::vector<vk::Pipeline> m_Pipelines;
std::vector<vk::PipelineLayout> m_PipelineLayouts;
uint64_t m_NextPipelineId;
std::vector<Pipeline> m_Pipelines;
void destroyPipelineById(uint64_t id);
public:
PipelineManager() = delete; // no default ctor
explicit PipelineManager(vk::Device device) noexcept; // ctor
......
......@@ -10,7 +10,7 @@ namespace vkcv {
SamplerManager::~SamplerManager() {
for (uint64_t id = 0; id < m_samplers.size(); id++) {
destroySampler(SamplerHandle(id));
destroySamplerById(id);
}
}
......@@ -96,7 +96,7 @@ namespace vkcv {
const uint64_t id = m_samplers.size();
m_samplers.push_back(sampler);
return SamplerHandle(id);
return SamplerHandle(id, [&](uint64_t id) { destroySamplerById(id); });
}
vk::Sampler SamplerManager::getVulkanSampler(const SamplerHandle &handle) const {
......@@ -109,9 +109,7 @@ namespace vkcv {
return m_samplers[id];
}
void SamplerManager::destroySampler(const SamplerHandle &handle) {
const uint64_t id = handle.getId();
void SamplerManager::destroySamplerById(uint64_t id) {
if (id >= m_samplers.size()) {
return;
}
......
......@@ -18,6 +18,8 @@ namespace vkcv {
explicit SamplerManager(const vk::Device& device) noexcept;
void destroySamplerById(uint64_t id);
public:
~SamplerManager();
......@@ -34,8 +36,6 @@ namespace vkcv {
[[nodiscard]]
vk::Sampler getVulkanSampler(const SamplerHandle& handle) const;
void destroySampler(const SamplerHandle& handle);
};
......