Skip to content

Commit

Permalink
Making the generation of mipmap more generic
Browse files Browse the repository at this point in the history
  • Loading branch information
mklefrancois committed May 27, 2020
1 parent 74b97e8 commit 0f63638
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 25 deletions.
3 changes: 1 addition & 2 deletions nvvk/allocator_dedicated_vk.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -283,8 +283,7 @@ class AllocatorDedicated
vkCmdCopyBufferToImage(cmdBuff, stageBuffer.buffer, resultImage.image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &bufferCopyRegion);

// Setting final image layout
subresourceRange.levelCount = 1;
nvvk::cmdBarrierImageLayout(cmdBuff, resultImage.image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, layout_, subresourceRange);
nvvk::cmdBarrierImageLayout(cmdBuff, resultImage.image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, layout_);
}
else
{
Expand Down
1 change: 0 additions & 1 deletion nvvk/allocator_dma_vk.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,6 @@ class AllocatorDma
m_staging.cmdToImage(cmd, resultImage.image, offset, info.extent, subresource, size, data);

// Setting final image layout
subresourceRange.levelCount = 1;
nvvk::cmdBarrierImageLayout(cmd, resultImage.image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, layout);
}
else
Expand Down
1 change: 0 additions & 1 deletion nvvk/allocator_vma_vk.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,6 @@ class AllocatorVma
m_staging.cmdToImage(cmd, resultImage.image, offset, info.extent, subresource, size, data);

// Setting final image layout
subresourceRange.levelCount = 1;
nvvk::cmdBarrierImageLayout(cmd, resultImage.image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, layout);
}
else
Expand Down
43 changes: 25 additions & 18 deletions nvvk/images_vk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,8 @@ void cmdBarrierImageLayout(VkCommandBuffer cmdbuffer, VkImage image, VkImageLayo
{
VkImageSubresourceRange subresourceRange;
subresourceRange.aspectMask = aspectMask;
subresourceRange.levelCount = 1;
subresourceRange.layerCount = 1;
subresourceRange.levelCount = VK_REMAINING_MIP_LEVELS;
subresourceRange.layerCount = VK_REMAINING_ARRAY_LAYERS;
subresourceRange.baseMipLevel = 0;
subresourceRange.baseArrayLayer = 0;
cmdBarrierImageLayout(cmdbuffer, image, oldImageLayout, newImageLayout, subresourceRange);
Expand Down Expand Up @@ -230,27 +230,34 @@ VkImageCreateInfo makeImageCubeCreateInfo(const VkExtent2D& size, VkFormat forma
// A more sophisticated version could be done with computer shader
// We will publish how to in the future

void cmdGenerateMipmaps(VkCommandBuffer cmdBuf, VkImage image, VkFormat imageFormat, const VkExtent2D& size, uint32_t mipLevels)
void cmdGenerateMipmaps(VkCommandBuffer cmdBuf, VkImage image, VkFormat imageFormat, const VkExtent2D& size, uint32_t levelCount, uint32_t layerCount, VkImageLayout currentLayout)
{
// Transfer the top level image to a layout 'eTransferSrcOptimal` and its access to 'eTransferRead'
VkImageMemoryBarrier barrier{VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER};
barrier.subresourceRange.baseArrayLayer = 0;
barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
barrier.subresourceRange.baseMipLevel = 0;
barrier.subresourceRange.layerCount = 1;
barrier.subresourceRange.layerCount = layerCount;
barrier.subresourceRange.levelCount = 1;
barrier.image = image;
barrier.oldLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
barrier.oldLayout = currentLayout;
barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
barrier.srcAccessMask = 0;
barrier.srcAccessMask = accessFlagsForImageLayout(currentLayout);
barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
vkCmdPipelineBarrier(cmdBuf, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, 1, &barrier);
vkCmdPipelineBarrier(cmdBuf, pipelineStageForLayout(currentLayout), VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, 1, &barrier);

// transfer remaining mips to DST optimal
barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
barrier.subresourceRange.baseMipLevel = 1;
barrier.subresourceRange.levelCount = VK_REMAINING_MIP_LEVELS;
vkCmdPipelineBarrier(cmdBuf, pipelineStageForLayout(currentLayout), VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, 1, &barrier);


int32_t mipWidth = size.width;
int32_t mipHeight = size.height;

for(uint32_t i = 1; i < mipLevels; i++)
for(uint32_t i = 1; i < levelCount; i++)
{

VkImageBlit blit;
Expand All @@ -259,23 +266,23 @@ void cmdGenerateMipmaps(VkCommandBuffer cmdBuf, VkImage image, VkFormat imageFor
blit.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
blit.srcSubresource.mipLevel = i - 1;
blit.srcSubresource.baseArrayLayer = 0;
blit.srcSubresource.layerCount = 1;
blit.srcSubresource.layerCount = layerCount;
blit.dstOffsets[0] = {0, 0, 0};
blit.dstOffsets[1] = {mipWidth > 1 ? mipWidth / 2 : 1, mipHeight > 1 ? mipHeight / 2 : 1, 1};
blit.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
blit.dstSubresource.mipLevel = i;
blit.dstSubresource.baseArrayLayer = 0;
blit.dstSubresource.layerCount = 1;
blit.dstSubresource.layerCount = layerCount;

vkCmdBlitImage(cmdBuf, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1,
&blit, VK_FILTER_LINEAR);


// Next
if(i + 1 < mipLevels)
{
// Transition the current miplevel into a eTransferSrcOptimal layout, to be used as the source for the next one.
barrier.subresourceRange.baseMipLevel = i;
barrier.subresourceRange.levelCount = 1;
barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
Expand All @@ -291,14 +298,14 @@ void cmdGenerateMipmaps(VkCommandBuffer cmdBuf, VkImage image, VkFormat imageFor
mipHeight /= 2;
}

//Transition all miplevels into a eShaderReadOnlyOptimal layout.
// Transition all miplevels (now in VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL) back to currentLayout
barrier.subresourceRange.baseMipLevel = 0;
barrier.subresourceRange.levelCount = mipLevels;
barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
barrier.srcAccessMask = 0;
barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
vkCmdPipelineBarrier(cmdBuf, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, 0, nullptr, 0,
barrier.subresourceRange.levelCount = VK_REMAINING_MIP_LEVELS;
barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
barrier.newLayout = currentLayout;
barrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
barrier.dstAccessMask = accessFlagsForImageLayout(currentLayout);
vkCmdPipelineBarrier(cmdBuf, VK_PIPELINE_STAGE_TRANSFER_BIT, pipelineStageForLayout(currentLayout), 0, 0, nullptr, 0,
nullptr, 1, &barrier);
}

Expand Down
6 changes: 3 additions & 3 deletions nvvk/images_vk.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ VkImageViewCreateInfo makeImage2DViewCreateInfo(VkImage image,
uint32_t levels = VK_REMAINING_MIP_LEVELS,
const void* pNextImageView = nullptr);

void cmdGenerateMipmaps(VkCommandBuffer cmdBuf, VkImage image, VkFormat imageFormat, const VkExtent2D& size, uint32_t mipLevels);
void cmdGenerateMipmaps(VkCommandBuffer cmdBuf, VkImage image, VkFormat imageFormat, const VkExtent2D& size, uint32_t levelCount, uint32_t layerCount = 1, VkImageLayout currentLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
#ifdef VULKAN_HPP

inline void cmdBarrierImageLayout(vk::CommandBuffer cmdbuffer,
Expand Down Expand Up @@ -178,10 +178,10 @@ inline vk::ImageCreateInfo makeImageCubeCreateInfo(const vk::Extent2D& size,
static_cast<VkImageUsageFlags>(usage), mipmaps);
}

inline void cmdGenerateMipmaps(vk::CommandBuffer cmdBuf, vk::Image image, vk::Format imageFormat, const vk::Extent2D& size, uint32_t mipLevels)
inline void cmdGenerateMipmaps(vk::CommandBuffer cmdBuf, vk::Image image, vk::Format imageFormat, const vk::Extent2D& size, uint32_t levelCount, uint32_t layerCount = 1, vk::ImageLayout currentLayout = vk::ImageLayout::eShaderReadOnlyOptimal)
{
cmdGenerateMipmaps(static_cast<VkCommandBuffer>(cmdBuf), static_cast<VkImage>(image),
static_cast<VkFormat>(imageFormat), static_cast<VkExtent2D>(size), mipLevels);
static_cast<VkFormat>(imageFormat), static_cast<VkExtent2D>(size), levelCount, layerCount, static_cast<VkImageLayout>(currentLayout));
}

inline vk::ImageCreateInfo makeImage3DCreateInfo(const vk::Extent3D& size,
Expand Down

0 comments on commit 0f63638

Please sign in to comment.