Skip to content
Snippets Groups Projects
Verified Commit 44de61f2 authored by Tobias Frisch's avatar Tobias Frisch
Browse files

Implement image layout per mip level

parent a6d96903
No related branches found
No related tags found
No related merge requests found
...@@ -11,6 +11,8 @@ ...@@ -11,6 +11,8 @@
#include "vkcv/TypeGuard.hpp" #include "vkcv/TypeGuard.hpp"
#include <algorithm> #include <algorithm>
#include <cstdint>
#include <sys/types.h>
namespace vkcv { namespace vkcv {
...@@ -72,11 +74,15 @@ namespace vkcv { ...@@ -72,11 +74,15 @@ namespace vkcv {
void ImageManager::recordImageMipGenerationToCmdBuffer(vk::CommandBuffer cmdBuffer, void ImageManager::recordImageMipGenerationToCmdBuffer(vk::CommandBuffer cmdBuffer,
const ImageHandle &handle) { const ImageHandle &handle) {
auto &image = (*this) [handle]; auto &image = (*this) [handle];
recordImageLayoutTransition(handle, 0, 0, vk::ImageLayout::eGeneral, cmdBuffer); recordImageLayoutTransition(handle, 0, 0, vk::ImageLayout::eGeneral, cmdBuffer);
vk::ImageAspectFlags aspectMask = isDepthImageFormat(image.m_format) ? vk::ImageAspectFlags aspectFlags;
vk::ImageAspectFlagBits::eDepth : if (isDepthFormat(image.m_format)) {
vk::ImageAspectFlagBits::eColor; aspectFlags = vk::ImageAspectFlagBits::eDepth;
} else {
aspectFlags = vk::ImageAspectFlagBits::eColor;
}
uint32_t srcWidth = image.m_width; uint32_t srcWidth = image.m_width;
uint32_t srcHeight = image.m_height; uint32_t srcHeight = image.m_height;
...@@ -92,14 +98,18 @@ namespace vkcv { ...@@ -92,14 +98,18 @@ namespace vkcv {
for (uint32_t srcMip = 0; srcMip < image.m_viewPerMip.size() - 1; srcMip++) { for (uint32_t srcMip = 0; srcMip < image.m_viewPerMip.size() - 1; srcMip++) {
uint32_t dstMip = srcMip + 1; uint32_t dstMip = srcMip + 1;
vk::ImageBlit region( const vk::ImageBlit region(
vk::ImageSubresourceLayers(aspectMask, srcMip, 0, 1), vk::ImageSubresourceLayers(aspectFlags, srcMip, 0, image.m_layers.size()),
{ vk::Offset3D(0, 0, 0), vk::Offset3D(srcWidth, srcHeight, srcDepth) }, { vk::Offset3D(0, 0, 0), vk::Offset3D(srcWidth, srcHeight, srcDepth) },
vk::ImageSubresourceLayers(aspectMask, dstMip, 0, 1), vk::ImageSubresourceLayers(aspectFlags, dstMip, 0, image.m_layers.size()),
{ vk::Offset3D(0, 0, 0), vk::Offset3D(dstWidth, dstHeight, dstDepth) }); { vk::Offset3D(0, 0, 0), vk::Offset3D(dstWidth, dstHeight, dstDepth) }
);
//recordImageLayoutTransition(handle, 1, srcMip, vk::ImageLayout::eTransferSrcOptimal, cmdBuffer);
//recordImageLayoutTransition(handle, 1, dstMip, vk::ImageLayout::eTransferDstOptimal, cmdBuffer);
cmdBuffer.blitImage(image.m_handle, vk::ImageLayout::eGeneral, image.m_handle, cmdBuffer.blitImage(image.m_handle, image.m_layers[0].m_layouts[srcMip], image.m_handle,
vk::ImageLayout::eGeneral, region, vk::Filter::eLinear); image.m_layers[0].m_layouts[dstMip], region, vk::Filter::eLinear);
srcWidth = dstWidth; srcWidth = dstWidth;
srcHeight = dstHeight; srcHeight = dstHeight;
...@@ -108,9 +118,12 @@ namespace vkcv { ...@@ -108,9 +118,12 @@ namespace vkcv {
dstWidth = half(dstWidth); dstWidth = half(dstWidth);
dstHeight = half(dstHeight); dstHeight = half(dstHeight);
dstDepth = half(dstDepth); dstDepth = half(dstDepth);
recordImageMemoryBarrier(handle, cmdBuffer); recordImageMemoryBarrier(handle, cmdBuffer);
} }
//recordImageLayoutTransition(handle, 1, image.m_viewPerMip.size() - 1, vk::ImageLayout::eTransferSrcOptimal, cmdBuffer);
//recordImageLayoutTransition(handle, 0, 0, vk::ImageLayout::eGeneral, cmdBuffer);
} }
const ImageEntry &ImageManager::operator[](const ImageHandle &handle) const { const ImageEntry &ImageManager::operator[](const ImageHandle &handle) const {
...@@ -340,8 +353,12 @@ namespace vkcv { ...@@ -340,8 +353,12 @@ namespace vkcv {
arrayViews.push_back(device.createImageView(imageViewCreateInfo)); arrayViews.push_back(device.createImageView(imageViewCreateInfo));
} }
Vector<vk::ImageLayout> layers; Vector<ImageLayer> layers;
layers.resize(arrayLayers, vk::ImageLayout::eUndefined); layers.resize(arrayLayers);
for (auto& layer : layers) {
layer.m_layouts.resize(mipCount, vk::ImageLayout::eUndefined);
}
return add({ return add({
image, image,
...@@ -430,7 +447,7 @@ namespace vkcv { ...@@ -430,7 +447,7 @@ namespace vkcv {
vk::ImageMemoryBarrier barrier ( vk::ImageMemoryBarrier barrier (
vk::AccessFlagBits::eMemoryWrite, vk::AccessFlagBits::eMemoryWrite,
vk::AccessFlagBits::eMemoryRead, vk::AccessFlagBits::eMemoryRead,
image.m_layers[0], image.m_layers[imageSubresourceRange.baseArrayLayer].m_layouts[imageSubresourceRange.baseMipLevel],
newLayout, newLayout,
VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED,
VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED,
...@@ -467,8 +484,10 @@ namespace vkcv { ...@@ -467,8 +484,10 @@ namespace vkcv {
core.submitCommandStream(stream, false); core.submitCommandStream(stream, false);
for (auto& layer : image.m_layers) { for (uint32_t i = transitionBarrier.subresourceRange.baseArrayLayer; i < transitionBarrier.subresourceRange.layerCount; i++) {
layer = newLayout; for (uint32_t j = transitionBarrier.subresourceRange.baseMipLevel; j < transitionBarrier.subresourceRange.levelCount; j++) {
image.m_layers[i].m_layouts[j] = newLayout;
}
} }
} }
...@@ -495,29 +514,62 @@ namespace vkcv { ...@@ -495,29 +514,62 @@ namespace vkcv {
); );
} }
for (auto& layer : image.m_layers) { for (uint32_t i = transitionBarrier.subresourceRange.baseArrayLayer; i < transitionBarrier.subresourceRange.layerCount; i++) {
layer = newLayout; for (uint32_t j = transitionBarrier.subresourceRange.baseMipLevel; j < transitionBarrier.subresourceRange.levelCount; j++) {
image.m_layers[i].m_layouts[j] = newLayout;
}
} }
} }
void ImageManager::recordImageMemoryBarrier(const ImageHandle &handle, void ImageManager::recordImageMemoryBarrier(const ImageHandle &handle,
vk::CommandBuffer cmdBuffer) { vk::CommandBuffer cmdBuffer) {
auto &image = (*this) [handle]; auto &image = (*this) [handle];
const auto transitionBarrier = createImageLayoutTransitionBarrier(
image, const uint32_t mipLevelCount = image.m_viewPerMip.size();
0, bool mipLevelConsistency = true;
0,
image.m_layers[0] for (uint32_t i = 1; i < mipLevelCount; i++) {
); if (image.m_layers[0].m_layouts[i] != image.m_layers[0].m_layouts[0]) {
mipLevelConsistency = false;
}
}
if (mipLevelConsistency) {
const auto transitionBarrier = createImageLayoutTransitionBarrier(
image,
0,
0,
image.m_layers[0].m_layouts[0]
);
cmdBuffer.pipelineBarrier(
vk::PipelineStageFlagBits::eAllCommands,
vk::PipelineStageFlagBits::eAllCommands,
{},
nullptr,
nullptr,
transitionBarrier
);
} else {
for (uint32_t i = 0; i < mipLevelCount; i++) {
const auto transitionBarrier = createImageLayoutTransitionBarrier(
image,
1,
i,
image.m_layers[0].m_layouts[i]
);
cmdBuffer.pipelineBarrier(
vk::PipelineStageFlagBits::eAllCommands,
vk::PipelineStageFlagBits::eAllCommands,
{},
nullptr,
nullptr,
transitionBarrier
);
}
}
cmdBuffer.pipelineBarrier(
vk::PipelineStageFlagBits::eAllCommands,
vk::PipelineStageFlagBits::eAllCommands,
{},
nullptr,
nullptr,
transitionBarrier
);
} }
constexpr uint32_t getBytesPerPixel(vk::Format format) { constexpr uint32_t getBytesPerPixel(vk::Format format) {
...@@ -653,9 +705,9 @@ namespace vkcv { ...@@ -653,9 +705,9 @@ namespace vkcv {
cmdBuffer.resolveImage( cmdBuffer.resolveImage(
srcImage.m_handle, srcImage.m_handle,
srcImage.m_layers[0], srcImage.m_layers[0].m_layouts[0],
dstImage.m_handle, dstImage.m_handle,
dstImage.m_layers[0], dstImage.m_layers[0].m_layouts[0],
region region
); );
} }
...@@ -721,6 +773,7 @@ namespace vkcv { ...@@ -721,6 +773,7 @@ namespace vkcv {
assert(images.size() == views.size()); assert(images.size() == views.size());
m_swapchainImages.clear(); m_swapchainImages.clear();
for (size_t i = 0; i < images.size(); i++) { for (size_t i = 0; i < images.size(); i++) {
const ImageLayer layer = { { vk::ImageLayout::eUndefined } };
m_swapchainImages.push_back({ m_swapchainImages.push_back({
images [i], images [i],
nullptr, nullptr,
...@@ -730,7 +783,7 @@ namespace vkcv { ...@@ -730,7 +783,7 @@ namespace vkcv {
height, height,
1, 1,
format, format,
{ vk::ImageLayout::eUndefined }, { layer },
false false
}); });
} }
...@@ -740,7 +793,9 @@ namespace vkcv { ...@@ -740,7 +793,9 @@ namespace vkcv {
vk::ImageLayout layout) { vk::ImageLayout layout) {
auto &image = (*this) [handle]; auto &image = (*this) [handle];
for (auto& layer : image.m_layers) { for (auto& layer : image.m_layers) {
layer = layout; for (auto& level : layer.m_layouts) {
level = layout;
}
} }
} }
......
...@@ -25,6 +25,10 @@ namespace vkcv { ...@@ -25,6 +25,10 @@ namespace vkcv {
*/ */
bool isDepthImageFormat(vk::Format format); bool isDepthImageFormat(vk::Format format);
struct ImageLayer {
Vector<vk::ImageLayout> m_layouts;
};
struct ImageEntry { struct ImageEntry {
vk::Image m_handle; vk::Image m_handle;
vma::Allocation m_allocation; vma::Allocation m_allocation;
...@@ -37,7 +41,7 @@ namespace vkcv { ...@@ -37,7 +41,7 @@ namespace vkcv {
uint32_t m_depth; uint32_t m_depth;
vk::Format m_format; vk::Format m_format;
Vector<vk::ImageLayout> m_layers; Vector<ImageLayer> m_layers;
bool m_storage; bool m_storage;
}; };
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment