From b62991d967dcabeb78baf896d26955bd5dc05ebb Mon Sep 17 00:00:00 2001 From: Powei Feng Date: Thu, 19 Oct 2023 13:43:23 -0700 Subject: [PATCH] vk: support stencil format in swapchain (#7277) Fixes #7233 FIXES=302197523 --- filament/backend/src/vulkan/VulkanTexture.cpp | 4 +- filament/backend/src/vulkan/VulkanUtility.cpp | 9 ++-- filament/backend/src/vulkan/VulkanUtility.h | 6 +-- .../src/vulkan/platform/VulkanPlatform.cpp | 5 +-- .../platform/VulkanPlatformSwapChainImpl.cpp | 41 ++++++++++++++----- .../platform/VulkanPlatformSwapChainImpl.h | 1 + 6 files changed, 41 insertions(+), 25 deletions(-) diff --git a/filament/backend/src/vulkan/VulkanTexture.cpp b/filament/backend/src/vulkan/VulkanTexture.cpp index 3b1af971051..ec5c3fc93cf 100644 --- a/filament/backend/src/vulkan/VulkanTexture.cpp +++ b/filament/backend/src/vulkan/VulkanTexture.cpp @@ -144,7 +144,7 @@ VulkanTexture::VulkanTexture(VkDevice device, VkPhysicalDevice physicalDevice, // any kind of attachment (color or depth). const auto& limits = context.getPhysicalDeviceLimits(); if (imageInfo.usage & VK_IMAGE_USAGE_SAMPLED_BIT) { - samples = reduceSampleCount(samples, isDepthFormat(mVkFormat) + samples = reduceSampleCount(samples, isVkDepthFormat(mVkFormat) ? limits.sampledImageDepthSampleCounts : limits.sampledImageColorSampleCounts); } @@ -452,7 +452,7 @@ void VulkanTexture::transitionLayout(VkCommandBuffer cmdbuf, const VkImageSubres << "," << range.levelCount << ")" << " from=" << oldLayout << " to=" << newLayout << " format=" << mVkFormat - << " depth=" << isDepthFormat(mVkFormat) + << " depth=" << isVkDepthFormat(mVkFormat) << " slice-by-slice=" << transitionSliceBySlice << utils::io::endl; #endif diff --git a/filament/backend/src/vulkan/VulkanUtility.cpp b/filament/backend/src/vulkan/VulkanUtility.cpp index 5f17b8aabe7..612acb20e5d 100644 --- a/filament/backend/src/vulkan/VulkanUtility.cpp +++ b/filament/backend/src/vulkan/VulkanUtility.cpp @@ -638,14 +638,13 @@ VkImageAspectFlags getImageAspect(VkFormat format) { } } -bool isDepthFormat(VkFormat format) { +bool isVkDepthFormat(VkFormat format) { return (getImageAspect(format) & VK_IMAGE_ASPECT_DEPTH_BIT) != 0; } -// TODO: support stencil attachments -// bool isStencilFormat(VkFormat format) { -// return (getImageAspect(format) & VK_IMAGE_ASPECT_STENCIL_BIT) != 0; -// } +bool isVkStencilFormat(VkFormat format) { + return (getImageAspect(format) & VK_IMAGE_ASPECT_STENCIL_BIT) != 0; +} static uint32_t mostSignificantBit(uint32_t x) { return 1ul << (31ul - utils::clz(x)); } diff --git a/filament/backend/src/vulkan/VulkanUtility.h b/filament/backend/src/vulkan/VulkanUtility.h index 88253da5ffb..3ba35c75e69 100644 --- a/filament/backend/src/vulkan/VulkanUtility.h +++ b/filament/backend/src/vulkan/VulkanUtility.h @@ -41,10 +41,8 @@ VkShaderStageFlags getShaderStageFlags(ShaderStageFlags stageFlags); bool equivalent(const VkRect2D& a, const VkRect2D& b); bool equivalent(const VkExtent2D& a, const VkExtent2D& b); -bool isDepthFormat(VkFormat format); - -// TODO: support stencil attachments -// bool isStencilFormat(VkFormat format); +bool isVkDepthFormat(VkFormat format); +bool isVkStencilFormat(VkFormat format); VkImageAspectFlags getImageAspect(VkFormat format); uint8_t reduceSampleCount(uint8_t sampleCount, VkSampleCountFlags mask); diff --git a/filament/backend/src/vulkan/platform/VulkanPlatform.cpp b/filament/backend/src/vulkan/platform/VulkanPlatform.cpp index 208f04819b0..3f3502ce684 100644 --- a/filament/backend/src/vulkan/platform/VulkanPlatform.cpp +++ b/filament/backend/src/vulkan/platform/VulkanPlatform.cpp @@ -516,9 +516,8 @@ VkFormatList findAttachmentDepthFormats(VkPhysicalDevice device) { VK_FORMAT_D32_SFLOAT, VK_FORMAT_X8_D24_UNORM_PACK32, - // TODO: support stencil attachments - // VK_FORMAT_D32_SFLOAT_S8_UINT, - // VK_FORMAT_D24_UNORM_S8_UINT, + VK_FORMAT_D32_SFLOAT_S8_UINT, + VK_FORMAT_D24_UNORM_S8_UINT, }; std::vector selectedFormats; for (VkFormat format: formats) { diff --git a/filament/backend/src/vulkan/platform/VulkanPlatformSwapChainImpl.cpp b/filament/backend/src/vulkan/platform/VulkanPlatformSwapChainImpl.cpp index 578b81bd7c8..a5a31a8d95f 100644 --- a/filament/backend/src/vulkan/platform/VulkanPlatformSwapChainImpl.cpp +++ b/filament/backend/src/vulkan/platform/VulkanPlatformSwapChainImpl.cpp @@ -30,7 +30,7 @@ namespace { std::tuple createImageAndMemory(VulkanContext const& context, VkDevice device, VkExtent2D extent, VkFormat format) { - bool const isDepth = isDepthFormat(format); + bool const isDepth = isVkDepthFormat(format); // Filament expects blit() to work with any texture, so we almost always set these usage flags. // TODO: investigate performance implications of setting these flags. VkImageUsageFlags const blittable @@ -76,6 +76,14 @@ std::tuple createImageAndMemory(VulkanContext const& co return std::tuple(image, imageMemory); } +VkFormat selectDepthFormat(VkFormatList const& depthFormats, bool hasStencil) { + auto const formatItr = std::find_if(depthFormats.begin(), depthFormats.end(), + hasStencil ? isVkStencilFormat : isVkDepthFormat); + assert_invariant( + formatItr != depthFormats.end() && "Cannot find suitable swapchain depth format"); + return *formatItr; +} + }// anonymous namespace VulkanPlatformSwapChainImpl::VulkanPlatformSwapChainImpl(VulkanContext const& context, @@ -116,7 +124,8 @@ VulkanPlatformSurfaceSwapChain::VulkanPlatformSurfaceSwapChain(VulkanContext con mPhysicalDevice(physicalDevice), mSurface(surface), mFallbackExtent(fallbackExtent), - mUsesRGB((flags & backend::SWAP_CHAIN_CONFIG_SRGB_COLORSPACE) != 0) { + mUsesRGB((flags & backend::SWAP_CHAIN_CONFIG_SRGB_COLORSPACE) != 0), + mHasStencil((flags & backend::SWAP_CHAIN_HAS_STENCIL_BUFFER) != 0) { assert_invariant(surface); create(); } @@ -152,10 +161,15 @@ VkResult VulkanPlatformSurfaceSwapChain::create() { // Find a suitable surface format. FixedCapacityVector const surfaceFormats = enumerate(vkGetPhysicalDeviceSurfaceFormatsKHR, mPhysicalDevice, mSurface); - FixedCapacityVector expectedFormats - = {VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_B8G8R8A8_UNORM}; + std::array expectedFormats = { + VK_FORMAT_R8G8B8A8_UNORM, + VK_FORMAT_B8G8R8A8_UNORM, + }; if (mUsesRGB) { - expectedFormats = {VK_FORMAT_R8G8B8A8_SRGB, VK_FORMAT_B8G8R8A8_SRGB}; + expectedFormats = { + VK_FORMAT_R8G8B8A8_SRGB, + VK_FORMAT_B8G8R8A8_SRGB, + }; } for (VkSurfaceFormatKHR const& format: surfaceFormats) { if (std::any_of(expectedFormats.begin(), expectedFormats.end(), @@ -228,14 +242,18 @@ VkResult VulkanPlatformSurfaceSwapChain::create() { mSwapChainBundle.colors = enumerate(vkGetSwapchainImagesKHR, mDevice, mSwapchain); mSwapChainBundle.colorFormat = surfaceFormat.format; + mSwapChainBundle.depthFormat = + selectDepthFormat(mContext.getAttachmentDepthFormats(), mHasStencil); + mSwapChainBundle.depth = createImage(mSwapChainBundle.extent, mSwapChainBundle.depthFormat); + slog.i << "vkCreateSwapchain" << ": " << mSwapChainBundle.extent.width << "x" << mSwapChainBundle.extent.height << ", " << surfaceFormat.format << ", " << surfaceFormat.colorSpace << ", " - << mSwapChainBundle.colors.size() << ", " << caps.currentTransform << io::endl; + << "swapchain-size=" << mSwapChainBundle.colors.size() << ", " + << "identity-transform=" << (caps.currentTransform == 1) << ", " + << "depth=" << mSwapChainBundle.depthFormat + << io::endl; - auto const& depthFormats = mContext.getAttachmentDepthFormats(); - mSwapChainBundle.depthFormat = depthFormats[0]; - mSwapChainBundle.depth = createImage(mSwapChainBundle.extent, mSwapChainBundle.depthFormat); return result; } @@ -310,8 +328,9 @@ VulkanPlatformHeadlessSwapChain::VulkanPlatformHeadlessSwapChain(VulkanContext c images[i] = createImage(extent, mSwapChainBundle.colorFormat); } - auto const& depthFormats = mContext.getAttachmentDepthFormats(); - mSwapChainBundle.depthFormat = depthFormats[0]; + bool const hasStencil = (flags & backend::SWAP_CHAIN_HAS_STENCIL_BUFFER) != 0; + mSwapChainBundle.depthFormat = + selectDepthFormat(mContext.getAttachmentDepthFormats(), hasStencil); mSwapChainBundle.depth = createImage(extent, mSwapChainBundle.depthFormat); } diff --git a/filament/backend/src/vulkan/platform/VulkanPlatformSwapChainImpl.h b/filament/backend/src/vulkan/platform/VulkanPlatformSwapChainImpl.h index ae2d022bb4f..ac4e26c105f 100644 --- a/filament/backend/src/vulkan/platform/VulkanPlatformSwapChainImpl.h +++ b/filament/backend/src/vulkan/platform/VulkanPlatformSwapChainImpl.h @@ -108,6 +108,7 @@ struct VulkanPlatformSurfaceSwapChain : public VulkanPlatformSwapChainImpl { VkExtent2D const mFallbackExtent; bool mUsesRGB = false; + bool mHasStencil = false; bool mSuboptimal; };