From f0f0923f43adb4ab531ead970d8d1599b028e783 Mon Sep 17 00:00:00 2001 From: Jorge Garcia Galicia Date: Thu, 26 Feb 2026 11:21:39 -0800 Subject: [PATCH] Stencil support for VK backend In order to support stencil op in VK we need to: 1)Configure corresponding pipeline/render pass 2)Configure attachment/FB Previous PR (#9716) covers 1) This PR covers 2) This PR also makes the the following tests pass on VK BasicStencilBufferTest.StencilBuffer BasicStencilBufferTest.DepthAndStencilBuffer --- filament/backend/src/vulkan/VulkanDriver.cpp | 57 +++++++++---------- .../backend/src/vulkan/VulkanFboCache.cpp | 53 +++++++++-------- filament/backend/src/vulkan/VulkanFboCache.h | 8 +-- filament/backend/src/vulkan/VulkanHandles.cpp | 45 +++++++-------- filament/backend/src/vulkan/VulkanHandles.h | 16 +++--- .../backend/src/vulkan/VulkanReadPixels.cpp | 4 +- filament/backend/src/vulkan/VulkanTexture.cpp | 2 +- filament/backend/src/vulkan/utils/Image.cpp | 4 +- filament/backend/src/vulkan/utils/Image.h | 6 +- filament/backend/test/test_StencilBuffer.cpp | 3 +- 10 files changed, 100 insertions(+), 98 deletions(-) diff --git a/filament/backend/src/vulkan/VulkanDriver.cpp b/filament/backend/src/vulkan/VulkanDriver.cpp index e49b21cb2aa5..3b1447d38e58 100644 --- a/filament/backend/src/vulkan/VulkanDriver.cpp +++ b/filament/backend/src/vulkan/VulkanDriver.cpp @@ -944,28 +944,23 @@ void VulkanDriver::createRenderTargetR(Handle rth, } } - VulkanAttachment depthStencil[2] = {}; - if (depth.handle) { - depthStencil[0] = { - .texture = resource_ptr::cast(&mResourceManager, depth.handle), - .level = depth.level, + VulkanAttachment depthStencil; + // In VK you can only have one depth/stencil attachment on a RT. + // This can be a depth only, stencil only or depth and stencil combined. + // You cannot have separate depth and stencil attachment (unless you use Dynamic Rendering) + if (depth.handle || stencil.handle) { + assert_invariant(!depth.handle || !stencil.handle || (depth.handle == stencil.handle)); + // We assume that we have depth only attachment or that depth and stencil come in the depth attachment + // Except in the case there is a stencil only attachment + TargetBufferInfo depthStencilBuffer = depth.handle ? depth : stencil; + + depthStencil = { + .texture = resource_ptr::cast(&mResourceManager, depthStencilBuffer.handle), + .level = depthStencilBuffer.level, .layerCount = layerCount, - .layer = (uint8_t) depth.layer, + .layer = (uint8_t) depthStencilBuffer.layer, }; - UTILS_UNUSED_IN_RELEASE VkExtent2D extent = depthStencil[0].getExtent2D(); - tmin = { std::min(tmin.x, extent.width), std::min(tmin.y, extent.height) }; - tmax = { std::max(tmax.x, extent.width), std::max(tmax.y, extent.height) }; - attachmentCount++; - } - - if (stencil.handle) { - depthStencil[1] = { - .texture = resource_ptr::cast(&mResourceManager, stencil.handle), - .level = stencil.level, - .layerCount = layerCount, - .layer = (uint8_t) stencil.layer, - }; - UTILS_UNUSED_IN_RELEASE VkExtent2D extent = depthStencil[1].getExtent2D(); + UTILS_UNUSED_IN_RELEASE VkExtent2D extent = depthStencil.getExtent2D(); tmin = { std::min(tmin.x, extent.width), std::min(tmin.y, extent.height) }; tmax = { std::max(tmax.x, extent.width), std::max(tmax.y, extent.height) }; attachmentCount++; @@ -1969,9 +1964,9 @@ void VulkanDriver::beginRenderPass(Handle rth, const RenderPassP assert_invariant(rt == mDefaultRenderTarget || extent.width > 0 && extent.height > 0); #if FVK_ENABLED(FVK_DEBUG_TEXTURE) - if (rt->hasDepth()) { - auto depth = rt->getDepth(); - depth.texture->print(); + if (rt->hasDepthStencil()) { + auto depthStencil = rt->getDepthStencil(); + depthStencil.texture->print(); } #endif @@ -1986,15 +1981,19 @@ void VulkanDriver::beginRenderPass(Handle rth, const RenderPassP VkRect2D const scissor{ .offset = { 0, 0 }, .extent = extent }; vkCmdSetScissor(cmdbuffer, 0, 1, &scissor); - VulkanLayout currentDepthLayout = VulkanLayout::UNDEFINED; + VulkanLayout currentDepthStencilLayout = VulkanLayout::UNDEFINED; TargetBufferFlags clearVal = params.flags.clear; TargetBufferFlags discardEndVal = params.flags.discardEnd; - if (rt->hasDepth()) { + if (rt->hasDepthStencil()) { if (params.readOnlyDepthStencil & RenderPassParams::READONLY_DEPTH) { discardEndVal &= ~TargetBufferFlags::DEPTH; clearVal &= ~TargetBufferFlags::DEPTH; } - currentDepthLayout = VulkanLayout::DEPTH_ATTACHMENT; + if (params.readOnlyDepthStencil & RenderPassParams::READONLY_STENCIL) { + discardEndVal &= ~TargetBufferFlags::STENCIL; + clearVal &= ~TargetBufferFlags::STENCIL; + } + currentDepthStencilLayout = VulkanLayout::DEPTH_STENCIL_ATTACHMENT; } @@ -2004,7 +2003,7 @@ void VulkanDriver::beginRenderPass(Handle rth, const RenderPassP rpkey.clear = clearVal; rpkey.discardStart = discardStart; rpkey.discardEnd = discardEndVal; - rpkey.initialDepthLayout = currentDepthLayout; + rpkey.initialDepthStencilLayout = currentDepthStencilLayout; rpkey.subpassMask = uint8_t(params.subpassMask); fvkmemory::resource_ptr renderPass = @@ -2070,9 +2069,9 @@ void VulkanDriver::beginRenderPass(Handle rth, const RenderPassP renderPassInfo.clearValueCount++; } } - if (fbkey.depth) { + if (fbkey.depthStencil) { VkClearValue &clearValue = clearValues[renderPassInfo.clearValueCount++]; - clearValue.depthStencil = {(float) params.clearDepth, 0}; + clearValue.depthStencil = {(float) params.clearDepth, params.clearStencil}; } renderPassInfo.pClearValues = &clearValues[0]; } diff --git a/filament/backend/src/vulkan/VulkanFboCache.cpp b/filament/backend/src/vulkan/VulkanFboCache.cpp index e4aabdaf44ae..92fa78caca51 100644 --- a/filament/backend/src/vulkan/VulkanFboCache.cpp +++ b/filament/backend/src/vulkan/VulkanFboCache.cpp @@ -33,11 +33,11 @@ namespace filament::backend { bool VulkanFboCache::RenderPassEq::operator()(const RenderPassKey& k1, const RenderPassKey& k2) const { - if (k1.initialDepthLayout != k2.initialDepthLayout) return false; + if (k1.initialDepthStencilLayout != k2.initialDepthStencilLayout) return false; for (int i = 0; i < MRT::MAX_SUPPORTED_RENDER_TARGET_COUNT; i++) { if (k1.colorFormat[i] != k2.colorFormat[i]) return false; } - if (k1.depthFormat != k2.depthFormat) return false; + if (k1.depthStencilFormat != k2.depthStencilFormat) return false; if (k1.clear != k2.clear) return false; if (k1.discardStart != k2.discardStart) return false; if (k1.discardEnd != k2.discardEnd) return false; @@ -55,7 +55,7 @@ bool VulkanFboCache::FboKeyEqualFn::operator()(const FboKey& k1, const FboKey& k if (k1.height != k2.height) return false; if (k1.layers != k2.layers) return false; if (k1.samples != k2.samples) return false; - if (k1.depth != k2.depth) return false; + if (k1.depthStencil != k2.depthStencil) return false; for (int i = 0; i < MRT::MAX_SUPPORTED_RENDER_TARGET_COUNT; i++) { if (k1.color[i] != k2.color[i]) return false; if (k1.resolve[i] != k2.resolve[i]) return false; @@ -96,8 +96,8 @@ fvkmemory::resource_ptr VulkanFboCache::getFramebuffer(FboKey attachments[attachmentCount++] = attachment; } } - if (config.depth) { - attachments[attachmentCount++] = config.depth; + if (config.depthStencil) { + attachments[attachmentCount++] = config.depthStencil; } #if FVK_ENABLED(FVK_DEBUG_FBO_CACHE) @@ -151,26 +151,27 @@ fvkmemory::resource_ptr VulkanFboCache::getRenderPass( VkAttachmentReference inputAttachmentRef[MRT::MAX_SUPPORTED_RENDER_TARGET_COUNT] = {}; VkAttachmentReference colorAttachmentRefs[2][MRT::MAX_SUPPORTED_RENDER_TARGET_COUNT] = {}; VkAttachmentReference resolveAttachmentRef[MRT::MAX_SUPPORTED_RENDER_TARGET_COUNT] = {}; - VkAttachmentReference depthAttachmentRef = {}; + VkAttachmentReference depthStencilAttachmentRef = {}; - const bool hasDepth = config.depthFormat != VK_FORMAT_UNDEFINED; + const bool hasDepthOrStencil = fvkutils::isVkDepthFormat(config.depthStencilFormat) || + fvkutils::isVkStencilFormat(config.depthStencilFormat); VkSubpassDescription subpasses[2] = {{ .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS, .pInputAttachments = nullptr, .pColorAttachments = colorAttachmentRefs[0], .pResolveAttachments = resolveAttachmentRef, - .pDepthStencilAttachment = hasDepth ? &depthAttachmentRef : nullptr + .pDepthStencilAttachment = hasDepthOrStencil ? &depthStencilAttachmentRef : nullptr }, { .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS, .pInputAttachments = inputAttachmentRef, .pColorAttachments = colorAttachmentRefs[1], .pResolveAttachments = resolveAttachmentRef, - .pDepthStencilAttachment = hasDepth ? &depthAttachmentRef : nullptr + .pDepthStencilAttachment = hasDepthOrStencil ? &depthStencilAttachmentRef : nullptr }}; - // The attachment list contains: Color Attachments, Resolve Attachments, and Depth Attachment. + // The attachment list contains: Color Attachments, Resolve Attachments, and Depth/Stencil Attachment. // For simplicity, create an array that can hold the maximum possible number of attachments. // Note that this needs to have the same ordering as the corollary array in getFramebuffer. VkAttachmentDescription attachments[MRT::MAX_SUPPORTED_RENDER_TARGET_COUNT + MRT::MAX_SUPPORTED_RENDER_TARGET_COUNT + 1] = {}; @@ -310,22 +311,26 @@ fvkmemory::resource_ptr VulkanFboCache::getRenderPass( }; } - // Populate the Depth Attachment. - if (hasDepth) { - const bool clear = any(config.clear & TargetBufferFlags::DEPTH); - const bool discardStart = any(config.discardStart & TargetBufferFlags::DEPTH); - const bool discardEnd = any(config.discardEnd & TargetBufferFlags::DEPTH); - depthAttachmentRef.layout = fvkutils::getVkLayout(VulkanLayout::DEPTH_ATTACHMENT); - depthAttachmentRef.attachment = attachmentIndex; + // Populate the Depth/Stencil Attachment. + if (hasDepthOrStencil) { + const bool clearDepth = any(config.clear & TargetBufferFlags::DEPTH); + const bool discardStartDepth = any(config.discardStart & TargetBufferFlags::DEPTH); + const bool discardEndDepth = any(config.discardEnd & TargetBufferFlags::DEPTH); + const bool clearStencil = any(config.clear & TargetBufferFlags::STENCIL); + const bool discardStartStencil = any(config.discardStart & TargetBufferFlags::STENCIL); + const bool discardEndStencil = any(config.discardEnd & TargetBufferFlags::STENCIL); + + depthStencilAttachmentRef.layout = fvkutils::getVkLayout(VulkanLayout::DEPTH_STENCIL_ATTACHMENT); + depthStencilAttachmentRef.attachment = attachmentIndex; attachments[attachmentIndex++] = { - .format = config.depthFormat, + .format = config.depthStencilFormat, .samples = (VkSampleCountFlagBits) config.samples, - .loadOp = clear ? kClear : (discardStart ? kDontCare : kKeep), - .storeOp = discardEnd ? kDisableStore : kEnableStore, - .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE, - .stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE, - .initialLayout = fvkutils::getVkLayout(config.initialDepthLayout), - .finalLayout = fvkutils::getVkLayout(FINAL_DEPTH_ATTACHMENT_LAYOUT), + .loadOp = clearDepth ? kClear : (discardStartDepth ? kDontCare : kKeep), + .storeOp = discardEndDepth ? kDisableStore : kEnableStore, + .stencilLoadOp = clearStencil ? kClear : (discardStartStencil ? kDontCare : kKeep), + .stencilStoreOp = discardEndStencil ? kDisableStore : kEnableStore, + .initialLayout = fvkutils::getVkLayout(config.initialDepthStencilLayout), + .finalLayout = fvkutils::getVkLayout(FINAL_DEPTH_STENCIL_ATTACHMENT_LAYOUT), }; } renderPassInfo.attachmentCount = attachmentIndex; diff --git a/filament/backend/src/vulkan/VulkanFboCache.h b/filament/backend/src/vulkan/VulkanFboCache.h index 2668f78e3607..469955775b5b 100644 --- a/filament/backend/src/vulkan/VulkanFboCache.h +++ b/filament/backend/src/vulkan/VulkanFboCache.h @@ -43,18 +43,18 @@ class VulkanFboCache { public: constexpr static VulkanLayout FINAL_COLOR_ATTACHMENT_LAYOUT = VulkanLayout::COLOR_ATTACHMENT; constexpr static VulkanLayout FINAL_RESOLVE_ATTACHMENT_LAYOUT = VulkanLayout::COLOR_ATTACHMENT; - constexpr static VulkanLayout FINAL_DEPTH_ATTACHMENT_LAYOUT = VulkanLayout::DEPTH_ATTACHMENT; + constexpr static VulkanLayout FINAL_DEPTH_STENCIL_ATTACHMENT_LAYOUT = VulkanLayout::DEPTH_STENCIL_ATTACHMENT; // RenderPassKey is a small POD representing the immutable state that is used to construct // a VkRenderPass. It is hashed and used as a lookup key. struct alignas(8) RenderPassKey { VkFormat colorFormat[MRT::MAX_SUPPORTED_RENDER_TARGET_COUNT]; // 32 bytes - VkFormat depthFormat; // 4 bytes + VkFormat depthStencilFormat; // 4 bytes TargetBufferFlags clear; // 4 bytes TargetBufferFlags discardStart; // 4 bytes TargetBufferFlags discardEnd; // 4 bytes - VulkanLayout initialDepthLayout; // 1 byte + VulkanLayout initialDepthStencilLayout; // 1 byte uint8_t samples; // 1 byte uint8_t needsResolveMask; // 1 byte uint8_t usesLazilyAllocatedMemory; // 1 byte @@ -86,7 +86,7 @@ class VulkanFboCache { uint16_t samples; // 2 bytes VkImageView color[MRT::MAX_SUPPORTED_RENDER_TARGET_COUNT]; // 64 bytes VkImageView resolve[MRT::MAX_SUPPORTED_RENDER_TARGET_COUNT]; // 64 bytes - VkImageView depth; // 8 bytes + VkImageView depthStencil; // 8 bytes }; struct FboVal { fvkmemory::resource_ptr handle; diff --git a/filament/backend/src/vulkan/VulkanHandles.cpp b/filament/backend/src/vulkan/VulkanHandles.cpp index 6325d810743a..c1480bb0f815 100644 --- a/filament/backend/src/vulkan/VulkanHandles.cpp +++ b/filament/backend/src/vulkan/VulkanHandles.cpp @@ -287,13 +287,13 @@ void VulkanRenderTarget::bindSwapChain(fvkmemory::resource_ptr if (swapchain->getDepth()) { VulkanAttachment depth = createSwapchainAttachment(swapchain->getDepth()); mInfo->attachments.push_back(depth); - mInfo->depthIndex = 1; + mInfo->depthStencilIndex = 1; - rpkey.depthFormat = depth.getFormat(); - fbkey.depth = depth.getImageView(); + rpkey.depthStencilFormat = depth.getFormat(); + fbkey.depthStencil = depth.getImageView(); } else { - rpkey.depthFormat = VK_FORMAT_UNDEFINED; - fbkey.depth = VK_NULL_HANDLE; + rpkey.depthStencilFormat = VK_FORMAT_UNDEFINED; + fbkey.depthStencil = VK_NULL_HANDLE; } mInfo->colors.set(0); } @@ -307,12 +307,11 @@ VulkanRenderTarget::VulkanRenderTarget(VkDevice device, VkPhysicalDevice physica VulkanContext const& context, fvkmemory::ResourceManager* resourceManager, VmaAllocator allocator, VulkanCommands* commands, uint32_t width, uint32_t height, uint8_t samples, VulkanAttachment color[MRT::MAX_SUPPORTED_RENDER_TARGET_COUNT], - VulkanAttachment depthStencil[2], VulkanStagePool& stagePool, uint8_t layerCount) + VulkanAttachment depthStencil, VulkanStagePool& stagePool, uint8_t layerCount) : HwRenderTarget(width, height), mOffscreen(true), mProtected(false), mInfo(std::make_unique()) { - auto& depth = depthStencil[0]; // Constrain the sample count according to both kinds of sample count masks obtained from // VkPhysicalDeviceProperties. This is consistent with the VulkanTexture constructor. @@ -322,7 +321,7 @@ VulkanRenderTarget::VulkanRenderTarget(VkDevice device, VkPhysicalDevice physica auto& rpkey = mInfo->rpkey; rpkey.samples = samples; - rpkey.depthFormat = depth.getFormat(); + rpkey.depthStencilFormat = depthStencil.getFormat(); rpkey.viewCount = layerCount; auto& fbkey = mInfo->fbkey; @@ -383,27 +382,27 @@ VulkanRenderTarget::VulkanRenderTarget(VkDevice device, VkPhysicalDevice physica attachments.insert(attachments.end(), msaaAttachments.begin(), msaaAttachments.end()); } - if (depth.texture) { - auto depthTexture = depth.texture; - mInfo->depthIndex = (uint8_t) attachments.size(); - attachments.push_back(depth); - fbkey.depth = depth.getImageView(); + if (depthStencil.texture) { + auto depthStencilTexture = depthStencil.texture; + mInfo->depthStencilIndex = (uint8_t) attachments.size(); + attachments.push_back(depthStencil); + fbkey.depthStencil = depthStencil.getImageView(); if (samples > 1) { - mInfo->msaaDepthIndex = mInfo->depthIndex; - if (depthTexture->samples == 1) { + mInfo->msaaDepthStencilIndex = mInfo->depthStencilIndex; + if (depthStencilTexture->samples == 1) { // MSAA depth texture must have the mipmap count of 1 uint8_t const msLevel = 1; // Create sidecar MSAA texture for the depth attachment if it does not already // exist. - auto msaaTexture = initMsaaTexture(depthTexture, device, physicalDevice, context, + auto msaaTexture = initMsaaTexture(depthStencilTexture, device, physicalDevice, context, allocator, commands, resourceManager, msLevel, samples, stagePool); - mInfo->msaaDepthIndex = (uint8_t) attachments.size(); + mInfo->msaaDepthStencilIndex = (uint8_t) attachments.size(); VulkanAttachment msaaAttachment = { .texture = msaaTexture, .layerCount = layerCount, }; attachments.push_back(msaaAttachment); - fbkey.depth = msaaAttachment.getImageView(); + fbkey.depthStencil = msaaAttachment.getImageView(); } } } @@ -460,11 +459,11 @@ void VulkanRenderTarget::emitBarriersBeginRenderPass(VulkanCommandBuffer& comman barrier(attachments[i], VulkanLayout::COLOR_ATTACHMENT); } } - if (mInfo->depthIndex != Auxiliary::UNDEFINED_INDEX) { - barrier(attachments[mInfo->depthIndex], VulkanLayout::DEPTH_ATTACHMENT); + if (mInfo->depthStencilIndex != Auxiliary::UNDEFINED_INDEX) { + barrier(attachments[mInfo->depthStencilIndex], VulkanLayout::DEPTH_STENCIL_ATTACHMENT); } - if (mInfo->msaaDepthIndex != Auxiliary::UNDEFINED_INDEX) { - barrier(attachments[mInfo->msaaDepthIndex], VulkanLayout::DEPTH_ATTACHMENT); + if (mInfo->msaaDepthStencilIndex != Auxiliary::UNDEFINED_INDEX) { + barrier(attachments[mInfo->msaaDepthStencilIndex], VulkanLayout::DEPTH_STENCIL_ATTACHMENT); } } @@ -478,7 +477,7 @@ void VulkanRenderTarget::emitBarriersEndRenderPass(VulkanCommandBuffer& commands bool const isDepth = attachment.isDepth(); auto texture = attachment.texture; if (isDepth) { - texture->setLayout(range, VulkanFboCache::FINAL_DEPTH_ATTACHMENT_LAYOUT); + texture->setLayout(range, VulkanFboCache::FINAL_DEPTH_STENCIL_ATTACHMENT_LAYOUT); if (!texture->transitionLayout(&commands, range, VulkanLayout::DEPTH_SAMPLER)) { texture->attachmentToSamplerBarrier(&commands, range); } diff --git a/filament/backend/src/vulkan/VulkanHandles.h b/filament/backend/src/vulkan/VulkanHandles.h index 76b04dbf1374..da0f69b142d0 100644 --- a/filament/backend/src/vulkan/VulkanHandles.h +++ b/filament/backend/src/vulkan/VulkanHandles.h @@ -252,7 +252,7 @@ struct VulkanRenderTarget : private HwRenderTarget, fvkmemory::Resource { VulkanContext const& context, fvkmemory::ResourceManager* resourceManager, VmaAllocator allocator, VulkanCommands* commands, uint32_t width, uint32_t height, uint8_t samples, VulkanAttachment color[MRT::MAX_SUPPORTED_RENDER_TARGET_COUNT], - VulkanAttachment depthStencil[2], VulkanStagePool& stagePool, uint8_t layerCount); + VulkanAttachment depthStencil, VulkanStagePool& stagePool, uint8_t layerCount); ~VulkanRenderTarget(); @@ -284,12 +284,12 @@ struct VulkanRenderTarget : private HwRenderTarget, fvkmemory::Resource { return mInfo->attachments[0]; } - inline VulkanAttachment& getDepth() const { - assert_invariant(hasDepth()); + inline VulkanAttachment& getDepthStencil() const { + assert_invariant(hasDepthStencil()); if (mInfo->fbkey.samples == 1) { - return mInfo->attachments[mInfo->depthIndex]; + return mInfo->attachments[mInfo->depthStencilIndex]; } - return mInfo->attachments[mInfo->msaaDepthIndex]; + return mInfo->attachments[mInfo->msaaDepthStencilIndex]; } inline VulkanFboCache::RenderPassKey const& getRenderPassKey() const { @@ -306,7 +306,7 @@ struct VulkanRenderTarget : private HwRenderTarget, fvkmemory::Resource { uint8_t getColorTargetCount(VulkanRenderPassContext const& pass) const; - inline bool hasDepth() const { return mInfo->depthIndex != Auxiliary::UNDEFINED_INDEX; } + inline bool hasDepthStencil() const { return mInfo->depthStencilIndex != Auxiliary::UNDEFINED_INDEX; } inline bool isSwapChain() const { return !mOffscreen; } inline bool isProtected() const { return mProtected; } @@ -341,8 +341,8 @@ struct VulkanRenderTarget : private HwRenderTarget, fvkmemory::Resource { VulkanFboCache::FboKey fbkey = {}; std::vector attachments; utils::bitset32 colors; - int8_t depthIndex = UNDEFINED_INDEX; - int8_t msaaDepthIndex = UNDEFINED_INDEX; + int8_t depthStencilIndex = UNDEFINED_INDEX; + int8_t msaaDepthStencilIndex = UNDEFINED_INDEX; int8_t msaaIndex = UNDEFINED_INDEX; }; bool mOffscreen; diff --git a/filament/backend/src/vulkan/VulkanReadPixels.cpp b/filament/backend/src/vulkan/VulkanReadPixels.cpp index 8c4fcfb483b8..f2f221585c3e 100644 --- a/filament/backend/src/vulkan/VulkanReadPixels.cpp +++ b/filament/backend/src/vulkan/VulkanReadPixels.cpp @@ -124,9 +124,9 @@ void VulkanReadPixels::run(fvkmemory::resource_ptr srcTarget uint32_t const graphicsQueueFamilyIndex, PixelBufferDescriptor&& pbd, SelecteMemoryFunction const& selectMemoryFunc, OnReadCompleteFunction const& readCompleteFunc) { - bool const isDepth = pbd.format == PixelDataFormat::DEPTH_COMPONENT || + bool const isDepthStencil = pbd.format == PixelDataFormat::DEPTH_COMPONENT || pbd.format == PixelDataFormat::DEPTH_STENCIL; - VulkanAttachment const srcAttachment = isDepth ? srcTarget->getDepth() : srcTarget->getColor0(); + VulkanAttachment const srcAttachment = isDepthStencil ? srcTarget->getDepthStencil() : srcTarget->getColor0(); run(srcAttachment.texture, srcAttachment.level, srcAttachment.layer, x, y, width, height, graphicsQueueFamilyIndex, std::move(pbd), selectMemoryFunc, readCompleteFunc); } diff --git a/filament/backend/src/vulkan/VulkanTexture.cpp b/filament/backend/src/vulkan/VulkanTexture.cpp index f6721d3b6b83..7801748055a4 100644 --- a/filament/backend/src/vulkan/VulkanTexture.cpp +++ b/filament/backend/src/vulkan/VulkanTexture.cpp @@ -118,7 +118,7 @@ inline VulkanLayout getDefaultLayoutImpl(TextureUsage usage) { if (any(usage & TextureUsage::SAMPLEABLE)) { return VulkanLayout::DEPTH_SAMPLER; } - return VulkanLayout::DEPTH_ATTACHMENT; + return VulkanLayout::DEPTH_STENCIL_ATTACHMENT; } if (any(usage & TextureUsage::COLOR_ATTACHMENT)) { diff --git a/filament/backend/src/vulkan/utils/Image.cpp b/filament/backend/src/vulkan/utils/Image.cpp index b613bc95bc30..391ec29ef0bd 100644 --- a/filament/backend/src/vulkan/utils/Image.cpp +++ b/filament/backend/src/vulkan/utils/Image.cpp @@ -72,7 +72,7 @@ getVkTransition(const VulkanLayoutTransition& transition) { srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; srcStage = VK_PIPELINE_STAGE_TRANSFER_BIT; break; - case VulkanLayout::DEPTH_ATTACHMENT: + case VulkanLayout::DEPTH_STENCIL_ATTACHMENT: srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; srcStage = VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT; break; @@ -116,7 +116,7 @@ getVkTransition(const VulkanLayoutTransition& transition) { dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; dstStage = VK_PIPELINE_STAGE_TRANSFER_BIT; break; - case VulkanLayout::DEPTH_ATTACHMENT: + case VulkanLayout::DEPTH_STENCIL_ATTACHMENT: dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; dstStage = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT; diff --git a/filament/backend/src/vulkan/utils/Image.h b/filament/backend/src/vulkan/utils/Image.h index 19762a8bee22..675b5608a2ca 100644 --- a/filament/backend/src/vulkan/utils/Image.h +++ b/filament/backend/src/vulkan/utils/Image.h @@ -42,8 +42,8 @@ enum class VulkanLayout : uint8_t { TRANSFER_SRC, // For the destination of a copy operation. TRANSFER_DST, - // For using a depth texture as an attachment. - DEPTH_ATTACHMENT, + // For using a depth/stencil texture as an attachment. + DEPTH_STENCIL_ATTACHMENT, // For using a depth texture both as an attachment and as a sampler. DEPTH_SAMPLER, // For swapchain images that will be presented. @@ -77,7 +77,7 @@ constexpr inline VkImageLayout getVkLayout(VulkanLayout layout) { return VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; case VulkanLayout::TRANSFER_DST: return VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; - case VulkanLayout::DEPTH_ATTACHMENT: + case VulkanLayout::DEPTH_STENCIL_ATTACHMENT: return VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; case VulkanLayout::DEPTH_SAMPLER: return VK_IMAGE_LAYOUT_GENERAL; diff --git a/filament/backend/test/test_StencilBuffer.cpp b/filament/backend/test/test_StencilBuffer.cpp index f6b3ef801830..7761a9bd9529 100644 --- a/filament/backend/test/test_StencilBuffer.cpp +++ b/filament/backend/test/test_StencilBuffer.cpp @@ -126,7 +126,6 @@ class BasicStencilBufferTest : public BackendTest { TEST_F(BasicStencilBufferTest, StencilBuffer) { SKIP_IF(Backend::WEBGPU, "test cases fail in WebGPU, see b/424157731"); - SKIP_IF(Backend::VULKAN, "b/453776821"); auto& api = getDriverApi(); @@ -152,7 +151,7 @@ TEST_F(BasicStencilBufferTest, StencilBuffer) { TEST_F(BasicStencilBufferTest, DepthAndStencilBuffer) { SKIP_IF(Backend::WEBGPU, "test cases fail in WebGPU, see b/424157731"); - SKIP_IF(Backend::VULKAN, "b/453776965"); + auto& api = getDriverApi(); // Create two textures: a color and a stencil, and an associated RenderTarget.