diff --git a/filament/CMakeLists.txt b/filament/CMakeLists.txt index b978d2da1bd..12e5ca76691 100644 --- a/filament/CMakeLists.txt +++ b/filament/CMakeLists.txt @@ -214,6 +214,7 @@ set(PRIVATE_HDRS set(MATERIAL_SRCS src/materials/antiAliasing/fxaa.mat src/materials/antiAliasing/taa.mat + src/materials/blitDepth.mat src/materials/blitLow.mat src/materials/blitArray.mat src/materials/bloom/bloomDownsample.mat diff --git a/filament/backend/include/private/backend/DriverAPI.inc b/filament/backend/include/private/backend/DriverAPI.inc index 844841862b3..2e2f81d9d37 100644 --- a/filament/backend/include/private/backend/DriverAPI.inc +++ b/filament/backend/include/private/backend/DriverAPI.inc @@ -304,6 +304,7 @@ DECL_DRIVER_API_SYNCHRONOUS_0(bool, isProtectedContentSupported) DECL_DRIVER_API_SYNCHRONOUS_N(bool, isStereoSupported, backend::StereoscopicType, stereoscopicType) DECL_DRIVER_API_SYNCHRONOUS_0(bool, isParallelShaderCompileSupported) DECL_DRIVER_API_SYNCHRONOUS_0(bool, isDepthStencilResolveSupported) +DECL_DRIVER_API_SYNCHRONOUS_N(bool, isDepthStencilBlitSupported, backend::TextureFormat, format) DECL_DRIVER_API_SYNCHRONOUS_0(bool, isProtectedTexturesSupported) DECL_DRIVER_API_SYNCHRONOUS_0(uint8_t, getMaxDrawBuffers) DECL_DRIVER_API_SYNCHRONOUS_0(size_t, getMaxUniformBufferSize) diff --git a/filament/backend/src/metal/MetalDriver.mm b/filament/backend/src/metal/MetalDriver.mm index d5e8dbf981e..65d1c918033 100644 --- a/filament/backend/src/metal/MetalDriver.mm +++ b/filament/backend/src/metal/MetalDriver.mm @@ -806,6 +806,10 @@ return false; } +bool MetalDriver::isDepthStencilBlitSupported(TextureFormat format) { + return true; +} + bool MetalDriver::isProtectedTexturesSupported() { return false; } diff --git a/filament/backend/src/noop/NoopDriver.cpp b/filament/backend/src/noop/NoopDriver.cpp index 3eb88afe577..911f967413d 100644 --- a/filament/backend/src/noop/NoopDriver.cpp +++ b/filament/backend/src/noop/NoopDriver.cpp @@ -194,6 +194,10 @@ bool NoopDriver::isDepthStencilResolveSupported() { return true; } +bool NoopDriver::isDepthStencilBlitSupported(TextureFormat format) { + return true; +} + bool NoopDriver::isProtectedTexturesSupported() { return true; } diff --git a/filament/backend/src/opengl/OpenGLDriver.cpp b/filament/backend/src/opengl/OpenGLDriver.cpp index 15f7df08951..bad0bba635a 100644 --- a/filament/backend/src/opengl/OpenGLDriver.cpp +++ b/filament/backend/src/opengl/OpenGLDriver.cpp @@ -2023,6 +2023,10 @@ bool OpenGLDriver::isDepthStencilResolveSupported() { return true; } +bool OpenGLDriver::isDepthStencilBlitSupported(TextureFormat format) { + return true; +} + bool OpenGLDriver::isProtectedTexturesSupported() { return getContext().ext.EXT_protected_textures; } diff --git a/filament/backend/src/vulkan/VulkanBlitter.cpp b/filament/backend/src/vulkan/VulkanBlitter.cpp index c4316cf1ec8..cde45ad0d87 100644 --- a/filament/backend/src/vulkan/VulkanBlitter.cpp +++ b/filament/backend/src/vulkan/VulkanBlitter.cpp @@ -26,8 +26,6 @@ #include -#include "generated/vkshaders/vkshaders.h" - using namespace bluevk; using namespace utils; @@ -40,7 +38,6 @@ namespace { inline void blitFast(const VkCommandBuffer cmdbuffer, VkImageAspectFlags aspect, VkFilter filter, VulkanAttachment src, VulkanAttachment dst, const VkOffset3D srcRect[2], const VkOffset3D dstRect[2]) { - if constexpr (FVK_ENABLED(FVK_DEBUG_BLITTER)) { utils::slog.d << "Fast blit from=" << src.texture->getVkImage() << ",level=" << (int) src.level << " layout=" << src.getLayout() @@ -93,7 +90,6 @@ inline void blitFast(const VkCommandBuffer cmdbuffer, VkImageAspectFlags aspect, inline void resolveFast(const VkCommandBuffer cmdbuffer, VkImageAspectFlags aspect, VulkanAttachment src, VulkanAttachment dst) { - if constexpr (FVK_ENABLED(FVK_DEBUG_BLITTER)) { utils::slog.d << "Fast blit from=" << src.texture->getVkImage() << ",level=" << (int) src.level << " layout=" << src.getLayout() diff --git a/filament/backend/src/vulkan/VulkanConstants.h b/filament/backend/src/vulkan/VulkanConstants.h index b4974950ef5..03736d558d5 100644 --- a/filament/backend/src/vulkan/VulkanConstants.h +++ b/filament/backend/src/vulkan/VulkanConstants.h @@ -47,7 +47,7 @@ // granualarity of a renderpass. You can enable this along with FVK_DEBUG_DEBUG_UTILS to take // advantage of vkCmdBegin/EndDebugUtilsLabelEXT. You can also just enable this with // FVK_DEBUG_PRINT_GROUP_MARKERS to print the current marker to stdout. -#define FVK_DEBUG_GROUP_MARKERS 0x00000002 +#define FVK_DEBUG_GROUP_MARKERS 0x00000002 #define FVK_DEBUG_TEXTURE 0x00000004 #define FVK_DEBUG_LAYOUT_TRANSITION 0x00000008 @@ -112,7 +112,7 @@ static_assert(FVK_ENABLED(FVK_DEBUG_VALIDATION)); // end dependcy checks // Shorthand for combination of enabled debug flags -#if FVK_ENABLED(FVK_DEBUG_DEBUG_UTILS) || FVK_ENABLED(FVK_DEBUG_TEXTURE) +#if FVK_ENABLED(FVK_DEBUG_DEBUG_UTILS) && FVK_ENABLED(FVK_DEBUG_TEXTURE) #define FVK_ENABLED_DEBUG_SAMPLER_NAME 1 #else #define FVK_ENABLED_DEBUG_SAMPLER_NAME 0 diff --git a/filament/backend/src/vulkan/VulkanContext.h b/filament/backend/src/vulkan/VulkanContext.h index 7c60f576b35..bdc3af691a9 100644 --- a/filament/backend/src/vulkan/VulkanContext.h +++ b/filament/backend/src/vulkan/VulkanContext.h @@ -101,8 +101,12 @@ struct VulkanContext { return (uint32_t) VK_MAX_MEMORY_TYPES; } - inline VkFormatList const& getAttachmentDepthFormats() const { - return mDepthFormats; + inline VkFormatList const& getAttachmentDepthStencilFormats() const { + return mDepthStencilFormats; + } + + inline VkFormatList const& getBlittableDepthStencilFormats() const { + return mBlittableDepthStencilFormats; } inline VkPhysicalDeviceLimits const& getPhysicalDeviceLimits() const noexcept { @@ -131,7 +135,8 @@ struct VulkanContext { bool mDebugMarkersSupported = false; bool mDebugUtilsSupported = false; - VkFormatList mDepthFormats; + VkFormatList mDepthStencilFormats; + VkFormatList mBlittableDepthStencilFormats; // For convenience so that VulkanPlatform can initialize the private fields. friend class VulkanPlatform; diff --git a/filament/backend/src/vulkan/VulkanDriver.cpp b/filament/backend/src/vulkan/VulkanDriver.cpp index 2b2284e092e..dada1d695cd 100644 --- a/filament/backend/src/vulkan/VulkanDriver.cpp +++ b/filament/backend/src/vulkan/VulkanDriver.cpp @@ -921,6 +921,11 @@ bool VulkanDriver::isDepthStencilResolveSupported() { return false; } +bool VulkanDriver::isDepthStencilBlitSupported(TextureFormat format) { + auto const& formats = mContext.getBlittableDepthStencilFormats(); + return std::find(formats.begin(), formats.end(), getVkFormat(format)) != formats.end(); +} + bool VulkanDriver::isProtectedTexturesSupported() { return false; } @@ -1807,7 +1812,7 @@ void VulkanDriver::bindPipeline(PipelineState pipelineState) { // This fallback path is very flaky because the dummy texture might not have // matching characteristics. (e.g. if the missing texture is a 3D texture) if (UTILS_UNLIKELY(texture->getPrimaryImageLayout() == VulkanLayout::UNDEFINED)) { -#if FVK_ENABLED(FVK_DEBUG_TEXTURE) +#if FVK_ENABLED(FVK_DEBUG_TEXTURE) && FVK_ENABLED_DEBUG_SAMPLER_NAME utils::slog.w << "Uninitialized texture bound to '" << bindingToName[binding] << "'"; utils::slog.w << " in material '" << program->name.c_str() << "'"; utils::slog.w << " at binding point " << +binding << utils::io::endl; diff --git a/filament/backend/src/vulkan/VulkanImageUtility.cpp b/filament/backend/src/vulkan/VulkanImageUtility.cpp index 108a3f2b96a..ada9de0ae26 100644 --- a/filament/backend/src/vulkan/VulkanImageUtility.cpp +++ b/filament/backend/src/vulkan/VulkanImageUtility.cpp @@ -217,7 +217,7 @@ bool operator<(const VkImageSubresourceRange& a, const VkImageSubresourceRange& return false; } -#if FVK_ENABLED(FVK_DEBUG_LAYOUT_TRANSITION | FVK_DEBUG_TEXTURE) +#if FVK_ENABLED(FVK_DEBUG_LAYOUT_TRANSITION) || FVK_ENABLED(FVK_DEBUG_TEXTURE) #define CASE(VALUE) \ case filament::backend::VulkanLayout::VALUE: { \ out << #VALUE; \ diff --git a/filament/backend/src/vulkan/platform/VulkanPlatform.cpp b/filament/backend/src/vulkan/platform/VulkanPlatform.cpp index 1510669b285..c58e5d19d0a 100644 --- a/filament/backend/src/vulkan/platform/VulkanPlatform.cpp +++ b/filament/backend/src/vulkan/platform/VulkanPlatform.cpp @@ -344,13 +344,13 @@ std::tuple pruneExtensions(VkPhysicalDevice device, ExtensionSet newInstExts = instExts; ExtensionSet newDeviceExts = deviceExts; -#if FVK_ENABLED(FVK_DEBUG_DEBUG_UTILS) +#if FVK_ENABLED(FVK_DEBUG_DEBUG_UTILS) // debugUtils and debugMarkers extensions are used mutually exclusively. if (newInstExts.find(VK_EXT_DEBUG_UTILS_EXTENSION_NAME) != newInstExts.end() && newDeviceExts.find(VK_EXT_DEBUG_MARKER_EXTENSION_NAME) != newDeviceExts.end()) { newDeviceExts.erase(VK_EXT_DEBUG_MARKER_EXTENSION_NAME); } -#endif +#endif #if FVK_ENABLED(FVK_DEBUG_VALIDATION) // debugMarker must also request debugReport the instance extension. So check if that's present. @@ -500,7 +500,7 @@ VkPhysicalDevice selectPhysicalDevice(VkInstance instance, return device; } -VkFormatList findAttachmentDepthFormats(VkPhysicalDevice device) { +VkFormatList findAttachmentDepthStencilFormats(VkPhysicalDevice device) { VkFormatFeatureFlags const features = VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT; // The ordering here indicates the preference of choosing depth+stencil format. @@ -524,6 +524,28 @@ VkFormatList findAttachmentDepthFormats(VkPhysicalDevice device) { return ret; } +VkFormatList findBlittableDepthStencilFormats(VkPhysicalDevice device) { + std::vector selectedFormats; + VkFormatFeatureFlags const required = VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT | + VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT; + for (VkFormat format = (VkFormat) 1;;) { + if (isVkDepthFormat(format)) { + VkFormatProperties props; + vkGetPhysicalDeviceFormatProperties(device, format, &props); + if ((props.optimalTilingFeatures & required) == required) { + selectedFormats.push_back(format); + } + } + format = (VkFormat) (1 + (int) format); + if (format == VK_FORMAT_ASTC_12x12_SRGB_BLOCK) { + break; + } + } + VkFormatList ret(selectedFormats.size()); + std::copy(selectedFormats.begin(), selectedFormats.end(), ret.begin()); + return ret; +} + }// anonymous namespace using SwapChainPtr = VulkanPlatform::SwapChainPtr; @@ -669,9 +691,11 @@ Driver* VulkanPlatform::createDriver(void* sharedContext, "Debug utils should not be enabled in release build."); #endif - context.mDepthFormats = findAttachmentDepthFormats(mImpl->mPhysicalDevice); + context.mDepthStencilFormats = findAttachmentDepthStencilFormats(mImpl->mPhysicalDevice); + context.mBlittableDepthStencilFormats = + findBlittableDepthStencilFormats(mImpl->mPhysicalDevice); - assert_invariant(context.mDepthFormats.size() > 0); + assert_invariant(context.mDepthStencilFormats.size() > 0); #if FVK_ENABLED(FVK_DEBUG_VALIDATION) printDepthFormats(mImpl->mPhysicalDevice); diff --git a/filament/backend/src/vulkan/platform/VulkanPlatformSwapChainImpl.cpp b/filament/backend/src/vulkan/platform/VulkanPlatformSwapChainImpl.cpp index a5a31a8d95f..5627e2610c2 100644 --- a/filament/backend/src/vulkan/platform/VulkanPlatformSwapChainImpl.cpp +++ b/filament/backend/src/vulkan/platform/VulkanPlatformSwapChainImpl.cpp @@ -243,7 +243,7 @@ VkResult VulkanPlatformSurfaceSwapChain::create() { mSwapChainBundle.colors = enumerate(vkGetSwapchainImagesKHR, mDevice, mSwapchain); mSwapChainBundle.colorFormat = surfaceFormat.format; mSwapChainBundle.depthFormat = - selectDepthFormat(mContext.getAttachmentDepthFormats(), mHasStencil); + selectDepthFormat(mContext.getAttachmentDepthStencilFormats(), mHasStencil); mSwapChainBundle.depth = createImage(mSwapChainBundle.extent, mSwapChainBundle.depthFormat); slog.i << "vkCreateSwapchain" @@ -330,7 +330,7 @@ VulkanPlatformHeadlessSwapChain::VulkanPlatformHeadlessSwapChain(VulkanContext c bool const hasStencil = (flags & backend::SWAP_CHAIN_HAS_STENCIL_BUFFER) != 0; mSwapChainBundle.depthFormat = - selectDepthFormat(mContext.getAttachmentDepthFormats(), hasStencil); + selectDepthFormat(mContext.getAttachmentDepthStencilFormats(), hasStencil); mSwapChainBundle.depth = createImage(extent, mSwapChainBundle.depthFormat); } diff --git a/filament/src/PostProcessManager.cpp b/filament/src/PostProcessManager.cpp index e570a9f632f..9dd8b9d5ff9 100644 --- a/filament/src/PostProcessManager.cpp +++ b/filament/src/PostProcessManager.cpp @@ -265,6 +265,7 @@ static const PostProcessManager::MaterialInfo sMaterialList[] = { { "bilateralBlur", MATERIAL(BILATERALBLUR) }, { "bilateralBlurBentNormals", MATERIAL(BILATERALBLURBENTNORMALS) }, { "blitArray", MATERIAL(BLITARRAY) }, + { "blitDepth", MATERIAL(BLITDEPTH) }, { "bloomDownsample", MATERIAL(BLOOMDOWNSAMPLE) }, { "bloomDownsample2x", MATERIAL(BLOOMDOWNSAMPLE2X) }, { "bloomDownsample9", MATERIAL(BLOOMDOWNSAMPLE9) }, @@ -720,46 +721,16 @@ FrameGraphId PostProcessManager::screenSpaceAmbientOcclusion( * attachment, even if writes are not enabled. This restriction is lifted on desktop GL and * Vulkan. The Metal situation is unclear. * In this case, we need to duplicate the depth texture to use it as an attachment. - * The pass below that does this is automatically culled if not needed, which is decided by - * each backend. + * + * This is also needed in Vulkan for a similar reason. */ + FrameGraphId duplicateDepthOutput = {}; + if (!mWorkaroundAllowReadOnlyAncillaryFeedbackLoop) { + duplicateDepthOutput = blitDepth(fg, depth); + } - struct DuplicateDepthPassData { - FrameGraphId input; - FrameGraphId output; - }; - - // Needed for Vulkan and GLES. Some GLES implementations don't need it. Never needed for Metal. - auto& duplicateDepthPass = fg.addPass("Duplicate Depth Pass", - [&](FrameGraph::Builder& builder, auto& data) { - data.input = builder.read(depth, - FrameGraphTexture::Usage::BLIT_SRC); - - auto desc = builder.getDescriptor(data.input); - desc.levels = 1; // only copy the base level - - // create a new buffer for the copy - data.output = builder.createTexture("Depth Texture Copy", desc); - - // output is an attachment - data.output = builder.write(data.output, - FrameGraphTexture::Usage::BLIT_DST); - }, - [=](FrameGraphResources const& resources, auto const& data, DriverApi& driver) { - auto const& src = resources.getTexture(data.input); - auto const& dst = resources.getTexture(data.output); - auto const& srcSubDesc = resources.getSubResourceDescriptor(data.input); - auto const& dstSubDesc = resources.getSubResourceDescriptor(data.output); - auto const& desc = resources.getDescriptor(data.output); - assert_invariant(desc.samples == resources.getDescriptor(data.input).samples); - // here we can guarantee that src and dst format and size match, by construction. - driver.blit( - dst, dstSubDesc.level, dstSubDesc.layer, { 0, 0 }, - src, srcSubDesc.level, srcSubDesc.layer, { 0, 0 }, - { desc.width, desc.height }); - }); - - auto& SSAOPass = fg.addPass("SSAO Pass", + auto& SSAOPass = fg.addPass( + "SSAO Pass", [&](FrameGraph::Builder& builder, auto& data) { auto const& desc = builder.getDescriptor(depth); @@ -788,10 +759,7 @@ FrameGraphId PostProcessManager::screenSpaceAmbientOcclusion( // reading into it even though they were not written in the depth buffer. // The bilateral filter in the blur pass will ignore pixels at infinity. - auto depthAttachment = data.depth; - if (!mWorkaroundAllowReadOnlyAncillaryFeedbackLoop) { - depthAttachment = duplicateDepthPass->output; - } + auto depthAttachment = duplicateDepthOutput ? duplicateDepthOutput : data.depth; depthAttachment = builder.read(depthAttachment, FrameGraphTexture::Usage::DEPTH_ATTACHMENT); @@ -801,8 +769,7 @@ FrameGraphId PostProcessManager::screenSpaceAmbientOcclusion( .clearFlags = TargetBufferFlags::COLOR0 | TargetBufferFlags::COLOR1 }); }, - [=](FrameGraphResources const& resources, - auto const& data, DriverApi& driver) { + [=](FrameGraphResources const& resources, auto const& data, DriverApi& driver) { auto depth = resources.getTexture(data.depth); auto ssao = resources.getRenderPassInfo(); auto const& desc = resources.getDescriptor(data.depth); @@ -3043,7 +3010,7 @@ FrameGraphId PostProcessManager::blit(FrameGraph& fg, bool tr auto& ppQuadBlit = fg.addPass("blitting", [&](FrameGraph::Builder& builder, auto& data) { data.input = builder.sample(input); - data.output = builder.createTexture("upscaled output", outDesc); + data.output = builder.createTexture("blit output", outDesc); data.output = builder.write(data.output, FrameGraphTexture::Usage::COLOR_ATTACHMENT); builder.declareRenderPass(builder.getName(data.output), { @@ -3087,6 +3054,87 @@ FrameGraphId PostProcessManager::blit(FrameGraph& fg, bool tr return ppQuadBlit->output; } +FrameGraphId PostProcessManager::blitDepth(FrameGraph& fg, + FrameGraphId input) noexcept { + auto const& inputDesc = fg.getDescriptor(input); + filament::Viewport const vp = {0, 0, inputDesc.width, inputDesc.height}; + bool const hardwareBlitSupported = + mEngine.getDriverApi().isDepthStencilBlitSupported(inputDesc.format); + + struct BlitData { + FrameGraphId input; + FrameGraphId output; + }; + + if (hardwareBlitSupported) { + auto& depthPass = fg.addPass( + "Depth Blit", + [&](FrameGraph::Builder& builder, auto& data) { + data.input = builder.read(input, FrameGraphTexture::Usage::BLIT_SRC); + + auto desc = builder.getDescriptor(data.input); + desc.levels = 1;// only copy the base level + + // create a new buffer for the copy + data.output = builder.createTexture("depth blit output", desc); + + // output is an attachment + data.output = builder.write(data.output, FrameGraphTexture::Usage::BLIT_DST); + }, + [=](FrameGraphResources const& resources, auto const& data, DriverApi& driver) { + auto const& src = resources.getTexture(data.input); + auto const& dst = resources.getTexture(data.output); + auto const& srcSubDesc = resources.getSubResourceDescriptor(data.input); + auto const& dstSubDesc = resources.getSubResourceDescriptor(data.output); + auto const& desc = resources.getDescriptor(data.output); + assert_invariant(desc.samples == resources.getDescriptor(data.input).samples); + // here we can guarantee that src and dst format and size match, by + // construction. + driver.blit( + dst, dstSubDesc.level, dstSubDesc.layer, { 0, 0 }, + src, srcSubDesc.level, srcSubDesc.layer, { 0, 0 }, + { desc.width, desc.height }); + }); + return depthPass->output; + } + // Otherwise, we would do a shader-based blit. + + auto& ppQuadBlit = fg.addPass( + "Depth Blit (Shader)", + [&](FrameGraph::Builder& builder, auto& data) { + data.input = builder.sample(input); + // Note that this is a same size/format blit. + auto const& outputDesc = inputDesc; + data.output = builder.createTexture("depth blit output", outputDesc); + data.output = + builder.write(data.output, FrameGraphTexture::Usage::DEPTH_ATTACHMENT); + builder.declareRenderPass(builder.getName(data.output), + {.attachments = {.depth = {data.output}}}); + }, + [=](FrameGraphResources const& resources, auto const& data, DriverApi& driver) { + auto depth = resources.getTexture(data.input); + auto const& inputDesc = resources.getDescriptor(data.input); + auto out = resources.getRenderPassInfo(); + + // -------------------------------------------------------------------------------- + // set uniforms + PostProcessMaterial const& material = getPostProcessMaterial("blitDepth"); + auto* mi = material.getMaterialInstance(mEngine); + mi->setParameter("depth", depth, + { + .filterMag = SamplerMagFilter::NEAREST, + .filterMin = SamplerMinFilter::NEAREST, + }); + mi->setParameter("viewport", + float4{float(vp.left) / inputDesc.width, + float(vp.bottom) / inputDesc.height, float(vp.width) / inputDesc.width, + float(vp.height) / inputDesc.height}); + commitAndRender(out, material, driver); + }); + + return ppQuadBlit->output; +} + FrameGraphId PostProcessManager::resolve(FrameGraph& fg, const char* outputBufferName, FrameGraphId input, FrameGraphTexture::Descriptor outDesc) noexcept { @@ -3283,7 +3331,7 @@ FrameGraphId PostProcessManager::debugShadowCascades(FrameGra return debugShadowCascadePass->output; } -FrameGraphId PostProcessManager::debugCombineArrayTexture(FrameGraph& fg, +FrameGraphId PostProcessManager::debugCombineArrayTexture(FrameGraph& fg, bool translucent, FrameGraphId input, filament::Viewport const& vp, FrameGraphTexture::Descriptor const& outDesc, SamplerMagFilter filterMag, diff --git a/filament/src/PostProcessManager.h b/filament/src/PostProcessManager.h index 432a9e3fff3..76f5bcd325f 100644 --- a/filament/src/PostProcessManager.h +++ b/filament/src/PostProcessManager.h @@ -250,13 +250,17 @@ class PostProcessManager { FrameGraphTexture::Descriptor const& outDesc, bool translucent); - // upscale/downscale blitter using shaders + // color blitter using shaders FrameGraphId blit(FrameGraph& fg, bool translucent, FrameGraphId input, filament::Viewport const& vp, FrameGraphTexture::Descriptor const& outDesc, backend::SamplerMagFilter filterMag, backend::SamplerMinFilter filterMin) noexcept; + // depth blitter using shaders + FrameGraphId blitDepth(FrameGraph& fg, + FrameGraphId input) noexcept; + // Resolves base level of input and outputs a texture from outDesc. // outDesc with, height, format and samples will be overridden. FrameGraphId resolve(FrameGraph& fg, diff --git a/filament/src/materials/blitDepth.mat b/filament/src/materials/blitDepth.mat new file mode 100644 index 00000000000..c8536ad545c --- /dev/null +++ b/filament/src/materials/blitDepth.mat @@ -0,0 +1,42 @@ +material { + name : blitDepth, + parameters : [ + { + type : sampler2d, + name : depth, + precision: medium + }, + { + type : float4, + name : viewport, + precision: high + } + ], + outputs : [ + { + name : depth, + target : depth, + type : float + } + ], + variables : [ + vertex + ], + culling: none, + depthWrite : true, + depthCulling : false, + domain: postprocess, +} + +vertex { + void postProcessVertex(inout PostProcessVertexInputs postProcess) { + postProcess.vertex.xy = materialParams.viewport.xy + postProcess.normalizedUV * materialParams.viewport.zw; + postProcess.vertex.xy = uvToRenderTargetUV(postProcess.vertex.xy); + } +} + +fragment { + void postProcess(inout PostProcessInputs postProcess) { + postProcess.depth = textureLod(materialParams_depth, variable_vertex.xy, 0.0).r; + } +}