diff --git a/include/vkcv/Core.hpp b/include/vkcv/Core.hpp index 78574ffa83cecc1ef58c6da2af5e9ac0f4d2595c..3bf93706001484b807476ed712541e128c7cd572 100644 --- a/include/vkcv/Core.hpp +++ b/include/vkcv/Core.hpp @@ -13,6 +13,7 @@ #include "vkcv/PassConfig.hpp" #include "vkcv/Handles.hpp" #include "vkcv/Buffer.hpp" +#include "vkcv/Image.hpp" #include "vkcv/PipelineConfig.hpp" #include "CommandResources.hpp" #include "SyncResources.hpp" @@ -24,6 +25,7 @@ namespace vkcv class PassManager; class PipelineManager; class BufferManager; + class ImageManager; struct SubmitInfo { QueueType queueType; @@ -60,6 +62,7 @@ namespace vkcv std::unique_ptr<PassManager> m_PassManager; std::unique_ptr<PipelineManager> m_PipelineManager; std::unique_ptr<BufferManager> m_BufferManager; + std::unique_ptr<ImageManager> m_ImageManager; CommandResources m_CommandResources; SyncResources m_SyncResources; uint32_t m_currentSwapchainImageIndex; diff --git a/include/vkcv/Image.hpp b/include/vkcv/Image.hpp index 9b632c290989658dfae8154205e94ac7ab2e1a5e..3c211402ffdc00a3cf7ee10ef7d0e557589af121 100644 --- a/include/vkcv/Image.hpp +++ b/include/vkcv/Image.hpp @@ -9,7 +9,8 @@ namespace vkcv { class Image { public: - static Image create(ImageManager* manager); + static Image create(ImageManager* manager, uint32_t width, uint32_t height); + void switchImageLayout(vk::Format format, vk::ImageLayout oldLayout, vk::ImageLayout newLayout); private: ImageManager* const m_manager; const uint64_t m_handle_id; diff --git a/include/vkcv/ImageManager.hpp b/include/vkcv/ImageManager.hpp index b2957f6a5ae7ea8b0e4eab86828fb47463404bc6..bb4efef74289fa114f196be303d83580c5631c05 100644 --- a/include/vkcv/ImageManager.hpp +++ b/include/vkcv/ImageManager.hpp @@ -32,6 +32,7 @@ namespace vkcv { ImageManager& operator=(const ImageManager& other) = delete; void copyBufferToImage(vk::Buffer bufffer, vk::Image image, uint32_t width, uint32_t height); + void switchImageLayout(uint64_t id, vk::ImageLayout oldLayout, vk::ImageLayout newLayout); uint64_t createImage(uint32_t width, uint32_t height); diff --git a/src/vkcv/Image.cpp b/src/vkcv/Image.cpp index 4af32f97cb5501029325aeccd938790b6271680e..887bf3b29adcd1d7e9490ab2820545b28691d3a6 100644 --- a/src/vkcv/Image.cpp +++ b/src/vkcv/Image.cpp @@ -4,12 +4,17 @@ * @brief class for image handles */ #include "vkcv/Image.hpp" + namespace vkcv{ - Image Image::create(ImageManager* manager) + Image Image::create(ImageManager* manager, uint32_t width, uint32_t height) { - return Image(manager, manager->createImage()); + return Image(manager, manager->createImage(width, height)); } + void Image::switchImageLayout(vk::Format format, vk::ImageLayout oldLayout, vk::ImageLayout newLayout) + { + m_manager->switchImageLayout(m_handle_id, oldLayout, newLayout); + } Image::Image(ImageManager* manager, uint64_t id) : m_manager(manager), m_handle_id(id) diff --git a/src/vkcv/ImageManager.cpp b/src/vkcv/ImageManager.cpp index db60960d5543e698e2ab631f738b85694b10a365..c99f1b8a278f825c46f8fe7d3540ec47041d7be2 100644 --- a/src/vkcv/ImageManager.cpp +++ b/src/vkcv/ImageManager.cpp @@ -48,7 +48,7 @@ namespace vkcv { { vk::ImageCreateFlags createFlags; vk::ImageUsageFlags imageUsageFlags = (vk::ImageUsageFlagBits::eSampled | vk::ImageUsageFlagBits::eTransferDst); - vk::Format format = vk::Format::eR8G8B8A8Unorm; // als Argument variabel? + vk::Format format = vk::Format::eR8G8B8A8Unorm; // als Argument variabel const vk::Device& device = m_core->getContext().getDevice(); @@ -89,6 +89,53 @@ namespace vkcv { return id; } + void ImageManager::switchImageLayout(uint64_t id, vk::ImageLayout oldLayout, vk::ImageLayout newLayout) { + //alternativly we could use switch case for every variable to set + vk::AccessFlags sourceAccessMask; + vk::PipelineStageFlags sourceStage; + vk::AccessFlags destinationAccessMask; + vk::PipelineStageFlags destinationStage; + if (oldLayout == vk::ImageLayout::eUndefined && newLayout == vk::ImageLayout::eTransferDstOptimal) { + destinationAccessMask = vk::AccessFlagBits::eTransferWrite; + sourceStage = vk::PipelineStageFlagBits::eTopOfPipe; + destinationStage = vk::PipelineStageFlagBits::eTransfer; + } + else if (oldLayout == vk::ImageLayout::eTransferDstOptimal && newLayout == vk::ImageLayout::eShaderReadOnlyOptimal) { + sourceAccessMask = vk::AccessFlagBits::eTransferWrite; + destinationAccessMask = vk::AccessFlagBits::eShaderRead; + sourceStage = vk::PipelineStageFlagBits::eTransfer; + destinationStage = vk::PipelineStageFlagBits::eFragmentShader; + } + vk::ImageSubresourceRange imageSubresourceRange(vk::ImageAspectFlagBits::eColor , 0, 1, 0, 1); + ImageManager::Image image = m_images[id]; + vk::ImageMemoryBarrier imageMemoryBarrier( + sourceAccessMask, + destinationAccessMask, + oldLayout, + newLayout, + VK_QUEUE_FAMILY_IGNORED, + VK_QUEUE_FAMILY_IGNORED, + image.m_handle, + imageSubresourceRange + ); + SubmitInfo submitInfo; + submitInfo.queueType = QueueType::Present; //not sure + m_core->submitCommands( + submitInfo, + [sourceStage, destinationStage, imageMemoryBarrier](const vk::CommandBuffer& commandBuffer) { + commandBuffer.pipelineBarrier( + sourceStage, + destinationStage, + {}, + nullptr, + nullptr, + imageMemoryBarrier + ); + }, + []() {} + ); + } + void ImageManager::destroyImage(uint64_t id) { if (id >= m_images.size()) {