SpiecsEngine
 
Loading...
Searching...
No Matches

◆ GenerateMipmaps()

void Spices::VulkanImage::GenerateMipmaps ( VkFormat imageFormat,
int32_t texWidth,
int32_t texHeight ) const

Generate mipmaps with the VkImage.

Parameters
[in]imageFormatVkFormat.
[in]texWidthThe Image Width.
[in]texHeightThe Image Height.

Get video memory properties.

Must require VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT.

Instance a VkImageMemoryBarrier.

Use Custom Cmd.

Iter all mips.

@breif Pipeline Barrier.

Instance a VkImageBlit.

BitlImage.

Pipeline Barrier.

Pipeline Barrier.

Get video memory properties.

Must require VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT.

Instance a VkImageMemoryBarrier.

Use Custom Cmd.

Iter all mips.

@breif Pipeline Barrier.

Instance a VkImageBlit.

BitlImage.

Pipeline Barrier.

Pipeline Barrier.

Definition at line 601 of file VulkanImage.cpp.

602 {
604
608 VkFormatProperties formatProperties;
609 vkGetPhysicalDeviceFormatProperties(m_VulkanState.m_PhysicalDevice, imageFormat, &formatProperties);
610
614 if (!(formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT) &&
615 (formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_BLIT_SRC_BIT) &&
616 (formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_BLIT_DST_BIT))
617 {
618 SPICES_CORE_ERROR("texture image format does not support linear blitting!")
619 }
620
624 VkImageMemoryBarrier barrier{};
625 barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
626 barrier.image = m_Image;
627 barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
628 barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
629 barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
630 barrier.subresourceRange.baseArrayLayer = 0;
631 barrier.subresourceRange.layerCount = m_Layers;
632 barrier.subresourceRange.levelCount = 1;
633
637 VulkanCommandBuffer::CustomGraphicCmd(m_VulkanState, [&](const VkCommandBuffer& commandBuffer) {
638
642 for (uint32_t i = 1; i < m_MipLevels; i++)
643 {
644 const int pw = std::max(1, (m_Width >> (i - 1)));
645 const int ph = std::max(1, (m_Height >> (i - 1)));
646
647 const int w = std::max(1, m_Width >> i);
648 const int h = std::max(1, m_Height >> i);
649
650 barrier.subresourceRange.baseMipLevel = i - 1;
651 barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
652 barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
653 barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
654 barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
655
659 vkCmdPipelineBarrier(commandBuffer,
660 VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0,
661 0, nullptr,
662 0, nullptr,
663 1, &barrier
664 );
665
669 VkImageBlit blit{};
670 blit.srcOffsets[0] = { 0, 0, 0 };
671 blit.srcOffsets[1] = { pw, ph, 1 };
672 blit.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
673 blit.srcSubresource.mipLevel = i - 1;
674 blit.srcSubresource.baseArrayLayer = 0;
675 blit.srcSubresource.layerCount = m_Layers;
676 blit.dstOffsets[0] = { 0, 0, 0 };
677 blit.dstOffsets[1] = { w, h, 1 };
678 blit.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
679 blit.dstSubresource.mipLevel = i;
680 blit.dstSubresource.baseArrayLayer = 0;
681 blit.dstSubresource.layerCount = m_Layers;
682
686 vkCmdBlitImage(commandBuffer,
687 m_Image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
688 m_Image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
689 1, &blit,
690 VK_FILTER_LINEAR
691 );
692
693 barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
694 barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
695 barrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
696 barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
697
701 vkCmdPipelineBarrier(commandBuffer,
702 VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0,
703 0, nullptr,
704 0, nullptr,
705 1, &barrier
706 );
707 }
708
709 barrier.subresourceRange.baseMipLevel = m_MipLevels - 1;
710 barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
711 barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
712 barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
713 barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
714
718 vkCmdPipelineBarrier(commandBuffer,
719 VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0,
720 0, nullptr,
721 0, nullptr,
722 1, &barrier
723 );
724 });
725 }
#define SPICES_PROFILE_ZONE
static void CustomGraphicCmd(VulkanState &vulkanState, T func)
Create a new command buffer and record custom cmd, submit to graphic queue, execute it immediately.
int m_Width
Image width.
uint32_t m_MipLevels
Image mipmaps num.
int m_Height
Image height.
VkImage m_Image
The VkImage this Class Wrapped.
uint32_t m_Layers
Image layer(texture cube: 6).
VulkanState & m_VulkanState
The global VulkanState Referenced from VulkanRenderBackend.
VkPhysicalDevice m_PhysicalDevice
Definition VulkanUtils.h:95

References m_Height, m_MipLevels, Spices::VulkanObject::m_VulkanState, and m_Width.