From 3d8fb3bceaa0451eecd3ce9005fdfa095e96673a Mon Sep 17 00:00:00 2001 From: Powei Feng Date: Thu, 11 Sep 2025 09:48:50 -0700 Subject: [PATCH] vk: fix blitDEPRECATED implementation (#9201) blitDEPRECATED can also be used in the context of a multisampled texture resolve. Fix that case to use the resolve() path in the VulkanBlitter. Also fixed backend test BlitTest.ColorResolve to add the correct usage bit (otherwise it'd have validation error). FIXES=417229577 --- filament/backend/src/vulkan/VulkanBlitter.cpp | 4 +--- filament/backend/src/vulkan/VulkanDriver.cpp | 11 ++++++++--- filament/backend/test/test_Blit.cpp | 11 ++++++----- 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/filament/backend/src/vulkan/VulkanBlitter.cpp b/filament/backend/src/vulkan/VulkanBlitter.cpp index 79ec183941..a672fc2198 100644 --- a/filament/backend/src/vulkan/VulkanBlitter.cpp +++ b/filament/backend/src/vulkan/VulkanBlitter.cpp @@ -96,7 +96,6 @@ inline void resolveFast(VulkanCommandBuffer* commands, VkImageAspectFlags aspect VulkanLayout oldSrcLayout = src.getLayout(); VulkanLayout oldDstLayout = dst.getLayout(); - src.texture->transitionLayout(commands, srcRange, VulkanLayout::TRANSFER_SRC); dst.texture->transitionLayout(commands, dstRange, VulkanLayout::TRANSFER_DST); assert_invariant( @@ -109,10 +108,9 @@ inline void resolveFast(VulkanCommandBuffer* commands, VkImageAspectFlags aspect .extent = { src.getExtent2D().width, src.getExtent2D().height, 1 }, }}; vkCmdResolveImage(cmdbuffer, - src.getImage(), fvkutils::getVkLayout(VulkanLayout::TRANSFER_SRC), + src.getImage(), fvkutils::getVkLayout(src.getLayout()), dst.getImage(), fvkutils::getVkLayout(VulkanLayout::TRANSFER_DST), 1, resolveRegions); - if (oldSrcLayout == VulkanLayout::UNDEFINED) { oldSrcLayout = src.texture->getDefaultLayout(); } diff --git a/filament/backend/src/vulkan/VulkanDriver.cpp b/filament/backend/src/vulkan/VulkanDriver.cpp index 9bceec25f3..53abfa661d 100644 --- a/filament/backend/src/vulkan/VulkanDriver.cpp +++ b/filament/backend/src/vulkan/VulkanDriver.cpp @@ -1891,9 +1891,14 @@ void VulkanDriver::blitDEPRECATED(TargetBufferFlags buffers, VkOffset3D const srcOffsets[2] = { { srcLeft, srcTop, 0 }, { srcRight, srcBottom, 1 }}; VkOffset3D const dstOffsets[2] = { { dstLeft, dstTop, 0 }, { dstRight, dstBottom, 1 }}; - mBlitter.blit(vkfilter, - dstTarget->getColor0(), dstOffsets, - srcTarget->getColor0(), srcOffsets); + auto const& dstAttachment = dstTarget->getColor0(); + auto const& srcAttachment = srcTarget->getColor0(); + + if (srcAttachment.texture->samples > 1) { + mBlitter.resolve(dstAttachment, srcAttachment); + } else { + mBlitter.blit(vkfilter, dstAttachment, dstOffsets, srcAttachment, srcOffsets); + } } void VulkanDriver::bindPipeline(PipelineState const& pipelineState) { diff --git a/filament/backend/test/test_Blit.cpp b/filament/backend/test/test_Blit.cpp index 6b58fbff84..636dc40f10 100644 --- a/filament/backend/test/test_Blit.cpp +++ b/filament/backend/test/test_Blit.cpp @@ -265,8 +265,6 @@ TEST_F(BlitTest, ColorMinify) { TEST_F(BlitTest, ColorResolve) { SKIP_IF(Backend::WEBGPU, "test cases fail in WebGPU, see b/424157731"); - NONFATAL_FAIL_IF(SkipEnvironment(OperatingSystem::APPLE, Backend::VULKAN), - "Nothing is drawn, see b/417229577"); auto& api = getDriverApi(); constexpr int kSrcTexWidth = 256; @@ -291,18 +289,21 @@ TEST_F(BlitTest, ColorResolve) { 1, TextureUsage::COLOR_ATTACHMENT | TextureUsage::BLIT_SRC | TextureUsage::UPLOADABLE)); // Create 1-sample texture. + // Note that BLIT_SRC usage is necessary because this texture will be read back. Handle const dstColorTexture = mCleanup.add(api.createTexture( SamplerType::SAMPLER_2D, 1, kColorTexFormat, 1, kDstTexWidth, kDstTexHeight, 1, - TextureUsage::SAMPLEABLE | TextureUsage::COLOR_ATTACHMENT | TextureUsage::BLIT_DST)); + TextureUsage::SAMPLEABLE | TextureUsage::COLOR_ATTACHMENT | TextureUsage::BLIT_DST | + TextureUsage::BLIT_SRC)); + // Create a 4-sample render target with the 4-sample texture. Handle const srcRenderTarget = mCleanup.add(api.createRenderTarget( - TargetBufferFlags::COLOR, kSrcTexWidth, kSrcTexHeight, kSampleCount, 0, + TargetBufferFlags::COLOR, kSrcTexWidth, kSrcTexHeight, kSampleCount, 1, {{ srcColorTexture }}, {}, {})); // Create a 1-sample render target with the 1-sample texture. Handle const dstRenderTarget = mCleanup.add(api.createRenderTarget( - TargetBufferFlags::COLOR, kDstTexWidth, kDstTexHeight, 1, 0, + TargetBufferFlags::COLOR, kDstTexWidth, kDstTexHeight, 1, 1, {{ dstColorTexture }}, {}, {})); // Prep for rendering.