vk: Fix unsupported depth blitting (#7789)
* vk: Fix unsupported depth blitting On certain hardware (pixel 4 for example), blitting of depth texture is not supported as an "optimalTilingFeature". In these cases, we'd would need to do a shader-based blit. We - Add the shader blit in PostProcessingManager - Add a driver API to check for support for blitting depthStencil attachments. - Fix some debugging ifdefs in vk backend. The validation fixed is: `[ VUID-vkCmdBlitImage-dstImage-02000 ] Object 0: handle = 0xb400007c300701d0, type = VK_OBJECT_TYPE_COMMAND_BUFFER; Object 1: handle = 0xf2039b0000000771, type = VK_OBJECT_TYPE_IMAGE; | MessageID = 0x86bc2a78 | In vkCmdBlitImage, VkFormatFeatureFlags (0x1c601) does not support required feature VK_FORMAT_FEATURE_2_BLIT_DST_BIT for format 126 used by VkImage 0xf2039b0000000771[] with tiling VK_IMAGE_TILING_OPTIMAL. The Vulkan spec states: The format features of dstImage must contain VK_FORMAT_FEATURE_BLIT_DST_BIT`
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -806,6 +806,10 @@ bool MetalDriver::isDepthStencilResolveSupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MetalDriver::isDepthStencilBlitSupported(TextureFormat format) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MetalDriver::isProtectedTexturesSupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -194,6 +194,10 @@ bool NoopDriver::isDepthStencilResolveSupported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NoopDriver::isDepthStencilBlitSupported(TextureFormat format) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NoopDriver::isProtectedTexturesSupported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -26,8 +26,6 @@
|
||||
|
||||
#include <smolv.h>
|
||||
|
||||
#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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -101,8 +101,12 @@ public:
|
||||
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 @@ private:
|
||||
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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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; \
|
||||
|
||||
@@ -344,13 +344,13 @@ std::tuple<ExtensionSet, ExtensionSet> 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<VkFormat> 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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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<FrameGraphTexture> 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<FrameGraphTexture> duplicateDepthOutput = {};
|
||||
if (!mWorkaroundAllowReadOnlyAncillaryFeedbackLoop) {
|
||||
duplicateDepthOutput = blitDepth(fg, depth);
|
||||
}
|
||||
|
||||
struct DuplicateDepthPassData {
|
||||
FrameGraphId<FrameGraphTexture> input;
|
||||
FrameGraphId<FrameGraphTexture> output;
|
||||
};
|
||||
|
||||
// Needed for Vulkan and GLES. Some GLES implementations don't need it. Never needed for Metal.
|
||||
auto& duplicateDepthPass = fg.addPass<DuplicateDepthPassData>("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<SSAOPassData>("SSAO Pass",
|
||||
auto& SSAOPass = fg.addPass<SSAOPassData>(
|
||||
"SSAO Pass",
|
||||
[&](FrameGraph::Builder& builder, auto& data) {
|
||||
auto const& desc = builder.getDescriptor(depth);
|
||||
|
||||
@@ -788,10 +759,7 @@ FrameGraphId<FrameGraphTexture> 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<FrameGraphTexture> 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<FrameGraphTexture> PostProcessManager::blit(FrameGraph& fg, bool tr
|
||||
auto& ppQuadBlit = fg.addPass<QuadBlitData>("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<FrameGraphTexture> PostProcessManager::blit(FrameGraph& fg, bool tr
|
||||
return ppQuadBlit->output;
|
||||
}
|
||||
|
||||
FrameGraphId<FrameGraphTexture> PostProcessManager::blitDepth(FrameGraph& fg,
|
||||
FrameGraphId<FrameGraphTexture> 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<FrameGraphTexture> input;
|
||||
FrameGraphId<FrameGraphTexture> output;
|
||||
};
|
||||
|
||||
if (hardwareBlitSupported) {
|
||||
auto& depthPass = fg.addPass<BlitData>(
|
||||
"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<BlitData>(
|
||||
"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<FrameGraphTexture> PostProcessManager::resolve(FrameGraph& fg,
|
||||
const char* outputBufferName, FrameGraphId<FrameGraphTexture> input,
|
||||
FrameGraphTexture::Descriptor outDesc) noexcept {
|
||||
@@ -3283,7 +3331,7 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::debugShadowCascades(FrameGra
|
||||
return debugShadowCascadePass->output;
|
||||
}
|
||||
|
||||
FrameGraphId<FrameGraphTexture> PostProcessManager::debugCombineArrayTexture(FrameGraph& fg,
|
||||
FrameGraphId<FrameGraphTexture> PostProcessManager::debugCombineArrayTexture(FrameGraph& fg,
|
||||
bool translucent, FrameGraphId<FrameGraphTexture> input,
|
||||
filament::Viewport const& vp, FrameGraphTexture::Descriptor const& outDesc,
|
||||
SamplerMagFilter filterMag,
|
||||
|
||||
@@ -250,13 +250,17 @@ public:
|
||||
FrameGraphTexture::Descriptor const& outDesc,
|
||||
bool translucent);
|
||||
|
||||
// upscale/downscale blitter using shaders
|
||||
// color blitter using shaders
|
||||
FrameGraphId<FrameGraphTexture> blit(FrameGraph& fg, bool translucent,
|
||||
FrameGraphId<FrameGraphTexture> input,
|
||||
filament::Viewport const& vp, FrameGraphTexture::Descriptor const& outDesc,
|
||||
backend::SamplerMagFilter filterMag,
|
||||
backend::SamplerMinFilter filterMin) noexcept;
|
||||
|
||||
// depth blitter using shaders
|
||||
FrameGraphId<FrameGraphTexture> blitDepth(FrameGraph& fg,
|
||||
FrameGraphId<FrameGraphTexture> input) noexcept;
|
||||
|
||||
// Resolves base level of input and outputs a texture from outDesc.
|
||||
// outDesc with, height, format and samples will be overridden.
|
||||
FrameGraphId<FrameGraphTexture> resolve(FrameGraph& fg,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user