@@ -1497,7 +1497,7 @@ uint32_t VK_ContextImpl::findMemoryType(uint32_t typeFilter, VkMemoryPropertyFla
1497
1497
return ~0 ;
1498
1498
}
1499
1499
1500
- void VK_ContextImpl::transitionImageLayout (VkImage image, VkFormat format, VkImageLayout oldLayout, VkImageLayout newLayout)
1500
+ void VK_ContextImpl::transitionImageLayout (VkImage image, VkFormat format, VkImageLayout oldLayout, VkImageLayout newLayout, uint32_t mipLevels )
1501
1501
{
1502
1502
VkCommandBuffer commandBuffer = beginSingleTimeCommands ();
1503
1503
@@ -1510,7 +1510,7 @@ void VK_ContextImpl::transitionImageLayout(VkImage image, VkFormat format, VkIma
1510
1510
barrier.image = image;
1511
1511
barrier.subresourceRange .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1512
1512
barrier.subresourceRange .baseMipLevel = 0 ;
1513
- barrier.subresourceRange .levelCount = 1 ;
1513
+ barrier.subresourceRange .levelCount = mipLevels ;
1514
1514
barrier.subresourceRange .baseArrayLayer = 0 ;
1515
1515
barrier.subresourceRange .layerCount = 1 ;
1516
1516
@@ -1608,3 +1608,92 @@ void VK_ContextImpl::endSingleTimeCommands(VkCommandBuffer commandBuffer)
1608
1608
1609
1609
vkFreeCommandBuffers (device, commandPool, 1 , &commandBuffer);
1610
1610
}
1611
+
1612
+ void VK_ContextImpl::generateMipmaps (VkImage image, VkFormat imageFormat, int32_t texWidth, int32_t texHeight, uint32_t mipLevels)
1613
+ {
1614
+ VkFormatProperties formatProperties;
1615
+ vkGetPhysicalDeviceFormatProperties (physicalDevice, imageFormat, &formatProperties);
1616
+
1617
+ if (!(formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT)) {
1618
+ std::cerr << " texture image format does not support linear blitting!" << std::endl;
1619
+ }
1620
+
1621
+ VkCommandBuffer commandBuffer = beginSingleTimeCommands ();
1622
+
1623
+ VkImageMemoryBarrier barrier = {};
1624
+ barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
1625
+ barrier.image = image;
1626
+ barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
1627
+ barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
1628
+ barrier.subresourceRange .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1629
+ barrier.subresourceRange .baseArrayLayer = 0 ;
1630
+ barrier.subresourceRange .layerCount = 1 ;
1631
+ barrier.subresourceRange .levelCount = 1 ;
1632
+
1633
+ int32_t mipWidth = texWidth;
1634
+ int32_t mipHeight = texHeight;
1635
+
1636
+ for (uint32_t i = 1 ; i < mipLevels; i++) {
1637
+ barrier.subresourceRange .baseMipLevel = i - 1 ;
1638
+ barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
1639
+ barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
1640
+ barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
1641
+ barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
1642
+
1643
+ vkCmdPipelineBarrier (commandBuffer,
1644
+ VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0 ,
1645
+ 0 , nullptr ,
1646
+ 0 , nullptr ,
1647
+ 1 , &barrier);
1648
+
1649
+ VkImageBlit blit = {};
1650
+ blit.srcOffsets [0 ] = {0 , 0 , 0 };
1651
+ blit.srcOffsets [1 ] = {mipWidth, mipHeight, 1 };
1652
+ blit.srcSubresource .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1653
+ blit.srcSubresource .mipLevel = i - 1 ;
1654
+ blit.srcSubresource .baseArrayLayer = 0 ;
1655
+ blit.srcSubresource .layerCount = 1 ;
1656
+ blit.dstOffsets [0 ] = {0 , 0 , 0 };
1657
+ blit.dstOffsets [1 ] = { mipWidth > 1 ? mipWidth / 2 : 1 , mipHeight > 1 ? mipHeight / 2 : 1 , 1 };
1658
+ blit.dstSubresource .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1659
+ blit.dstSubresource .mipLevel = i;
1660
+ blit.dstSubresource .baseArrayLayer = 0 ;
1661
+ blit.dstSubresource .layerCount = 1 ;
1662
+
1663
+ vkCmdBlitImage (commandBuffer,
1664
+ image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1665
+ image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1666
+ 1 , &blit,
1667
+ VK_FILTER_LINEAR);
1668
+
1669
+ barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
1670
+ barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
1671
+ barrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
1672
+ barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
1673
+
1674
+ vkCmdPipelineBarrier (commandBuffer,
1675
+ VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0 ,
1676
+ 0 , nullptr ,
1677
+ 0 , nullptr ,
1678
+ 1 , &barrier);
1679
+
1680
+ if (mipWidth > 1 )
1681
+ mipWidth /= 2 ;
1682
+ if (mipHeight > 1 )
1683
+ mipHeight /= 2 ;
1684
+ }
1685
+
1686
+ barrier.subresourceRange .baseMipLevel = mipLevels - 1 ;
1687
+ barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
1688
+ barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
1689
+ barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
1690
+ barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
1691
+
1692
+ vkCmdPipelineBarrier (commandBuffer,
1693
+ VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0 ,
1694
+ 0 , nullptr ,
1695
+ 0 , nullptr ,
1696
+ 1 , &barrier);
1697
+
1698
+ endSingleTimeCommands (commandBuffer);
1699
+ }
0 commit comments