diff --git a/src/vkcv/ImageManager.cpp b/src/vkcv/ImageManager.cpp index 70b4a6016c5faddff7073589794af7c77dc0d2d0..6716024e25071db1ca41247179278d342d62c3cd 100644 --- a/src/vkcv/ImageManager.cpp +++ b/src/vkcv/ImageManager.cpp @@ -6,6 +6,8 @@ #include "ImageManager.hpp" #include "vkcv/Core.hpp" +#include <algorithm> + namespace vkcv { /** @@ -44,6 +46,16 @@ namespace vkcv { destroyImage(ImageHandle(id)); } } + + bool isDepthImageFormat(vk::Format format) { + if ((format == vk::Format::eD16Unorm) || (format == vk::Format::eD16UnormS8Uint) || + (format == vk::Format::eD24UnormS8Uint) || (format == vk::Format::eD32Sfloat) || + (format == vk::Format::eD32SfloatS8Uint)) { + return true; + } else { + return false; + } + } ImageHandle ImageManager::createImage(uint32_t width, uint32_t height, uint32_t depth, vk::Format format) { @@ -84,13 +96,16 @@ namespace vkcv { format, imageType, imageTiling, imageUsageFlags ); + const uint32_t mipLevels = std::min<uint32_t>(1, imageFormatProperties.maxMipLevels); + const uint32_t arrayLayers = std::min<uint32_t>(1, imageFormatProperties.maxArrayLayers); + const vk::ImageCreateInfo imageCreateInfo( createFlags, imageType, format, vk::Extent3D(width, height, depth), - 1, - 1, + mipLevels, + arrayLayers, vk::SampleCountFlagBits::e1, imageTiling, imageUsageFlags, @@ -114,6 +129,14 @@ namespace vkcv { vk::DeviceMemory memory = device.allocateMemory(vk::MemoryAllocateInfo(requirements.size, memoryTypeIndex)); device.bindImageMemory(image, memory, 0); + vk::ImageAspectFlags aspectFlags; + + if (isDepthImageFormat(format)) { + aspectFlags = vk::ImageAspectFlagBits::eDepth; + } else { + aspectFlags = vk::ImageAspectFlagBits::eColor; + } + const vk::ImageViewCreateInfo imageViewCreateInfo ( {}, image, @@ -126,18 +149,18 @@ namespace vkcv { vk::ComponentSwizzle::eIdentity ), vk::ImageSubresourceRange( - vk::ImageAspectFlagBits::eColor, + aspectFlags, 0, - 1, + mipLevels, 0, - 1 + arrayLayers ) ); vk::ImageView view = device.createImageView(imageViewCreateInfo); const uint64_t id = m_images.size(); - m_images.push_back({ image, memory, view, width, height, depth, format }); + m_images.push_back({ image, memory, view, width, height, depth, format, arrayLayers, mipLevels }); return ImageHandle(id); } @@ -178,6 +201,14 @@ namespace vkcv { } void ImageManager::switchImageLayout(const ImageHandle& handle, vk::ImageLayout oldLayout, vk::ImageLayout newLayout) { + const uint64_t id = handle.getId(); + + if (id >= m_images.size()) { + return; + } + + auto& image = m_images[id]; + //alternativly we could use switch case for every variable to set vk::AccessFlags sourceAccessMask; vk::PipelineStageFlags sourceStage; @@ -203,22 +234,22 @@ namespace vkcv { destinationStage = vk::PipelineStageFlagBits::eFragmentShader; } + vk::ImageAspectFlags aspectFlags; + + if (isDepthImageFormat(image.m_format)) { + aspectFlags = vk::ImageAspectFlagBits::eDepth; + } else { + aspectFlags = vk::ImageAspectFlagBits::eColor; + } + vk::ImageSubresourceRange imageSubresourceRange( - vk::ImageAspectFlagBits::eColor, + aspectFlags, 0, - 1, + image.m_levels, 0, - 1 + image.m_layers ); - const uint64_t id = handle.getId(); - - if (id >= m_images.size()) { - return; - } - - auto& image = m_images[id]; - vk::ImageMemoryBarrier imageMemoryBarrier( sourceAccessMask, destinationAccessMask, @@ -286,15 +317,23 @@ namespace vkcv { m_core->submitCommands( submitInfo, [&image, &stagingBuffer](const vk::CommandBuffer& commandBuffer) { + vk::ImageAspectFlags aspectFlags; + + if (isDepthImageFormat(image.m_format)) { + aspectFlags = vk::ImageAspectFlagBits::eDepth; + } else { + aspectFlags = vk::ImageAspectFlagBits::eColor; + } + const vk::BufferImageCopy region ( 0, 0, 0, vk::ImageSubresourceLayers( - vk::ImageAspectFlagBits::eColor, + aspectFlags, 0, 0, - 1 + image.m_layers ), vk::Offset3D(0, 0, 0), vk::Extent3D(image.m_width, image.m_height, image.m_depth) diff --git a/src/vkcv/ImageManager.hpp b/src/vkcv/ImageManager.hpp index 98c4e4e67bbe27eed453f655c56138200d78e5f4..7dc6746f37b7d03900302afbd0536b909f9e48fc 100644 --- a/src/vkcv/ImageManager.hpp +++ b/src/vkcv/ImageManager.hpp @@ -25,6 +25,8 @@ namespace vkcv { uint32_t m_height = 0; uint32_t m_depth = 0; vk::Format m_format; + uint32_t m_layers = 1; + uint32_t m_levels = 1; }; Core* m_core;