ppm: ensure a renderable descriptor set is bound

- We set a dummy set at the renderable bind point for
   post-processing passes, since it is not used.
This commit is contained in:
Powei Feng
2025-07-31 15:52:21 -07:00
parent ee8d0e6ebf
commit 2d518b5fd1
2 changed files with 83 additions and 1 deletions

View File

@@ -252,6 +252,11 @@ void PostProcessManager::bindPostProcessDescriptorSet(DriverApi& driver) const n
mPostProcessDescriptorSet.bind(driver);
}
void PostProcessManager::bindPerRenderableDescriptorSet(DriverApi& driver) noexcept {
driver.bindDescriptorSet(mDummyPerRenderableDsh, +DescriptorSetBindingPoints::PER_RENDERABLE,
{ { 0, 0 }, driver });
}
UTILS_NOINLINE
void PostProcessManager::registerPostProcessMaterial(std::string_view const name,
StaticMaterialInfo const& info) {
@@ -315,6 +320,32 @@ void PostProcessManager::init() noexcept {
mFullScreenQuadVbih = engine.getFullScreenVertexBuffer()->getVertexBufferInfoHandle();
mPerRenderableDslh = engine.getPerRenderableDescriptorSetLayout().getHandle();
mDummyPerRenderableDsh = driver.createDescriptorSet(mPerRenderableDslh);
driver.updateDescriptorSetBuffer(mDummyPerRenderableDsh,
+PerRenderableBindingPoints::OBJECT_UNIFORMS, engine.getDummyUniformBuffer(), 0,
sizeof(PerRenderableUib));
driver.updateDescriptorSetBuffer(mDummyPerRenderableDsh,
+PerRenderableBindingPoints::BONES_UNIFORMS, engine.getDummyUniformBuffer(), 0,
sizeof(PerRenderableBoneUib));
driver.updateDescriptorSetBuffer(mDummyPerRenderableDsh,
+PerRenderableBindingPoints::MORPHING_UNIFORMS, engine.getDummyUniformBuffer(), 0,
sizeof(PerRenderableMorphingUib));
driver.updateDescriptorSetTexture(mDummyPerRenderableDsh,
+PerRenderableBindingPoints::MORPH_TARGET_POSITIONS,
engine.getDummyMorphTargetBuffer()->getPositionsHandle(), {});
driver.updateDescriptorSetTexture(mDummyPerRenderableDsh,
+PerRenderableBindingPoints::MORPH_TARGET_TANGENTS,
engine.getDummyMorphTargetBuffer()->getTangentsHandle(), {});
driver.updateDescriptorSetTexture(mDummyPerRenderableDsh,
+PerRenderableBindingPoints::BONES_INDICES_AND_WEIGHTS, engine.getZeroTextureArray(),
{});
mSsrPassDescriptorSet.init(engine);
mPostProcessDescriptorSet.init(engine);
mStructureDescriptorSet.init(engine);
@@ -385,6 +416,8 @@ void PostProcessManager::terminate(DriverApi& driver) noexcept {
FEngine& engine = mEngine;
driver.destroyTexture(mStarburstTexture);
driver.destroyDescriptorSet(mDummyPerRenderableDsh);
// Must destroy the instances before the materials
mMaterialInstanceManager.terminate(engine);
@@ -553,6 +586,7 @@ PostProcessManager::StructurePassOutput PostProcessManager::structure(FrameGraph
// bind the per-view descriptorSet that is used for the structure pass
getStructureDescriptorSet().bind(driver);
bindPerRenderableDescriptorSet(driver);
passBuilder.renderFlags(structureRenderFlags);
passBuilder.variant(structureVariant);
@@ -590,7 +624,8 @@ PostProcessManager::StructurePassOutput PostProcessManager::structure(FrameGraph
}
},
[=](FrameGraphResources const& resources, auto const& data, DriverApi& driver) {
getStructureDescriptorSet().bind(driver);
getStructureDescriptorSet().bind(driver);
bindPerRenderableDescriptorSet(driver);
auto in = resources.getTexture(data.depth);
auto& material = getPostProcessMaterial("mipmapDepth");
@@ -661,6 +696,7 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::transparentPicking(FrameGrap
// bind the per-view descriptorSet that is used for the structure pass
getStructureDescriptorSet().bind(driver);
bindPerRenderableDescriptorSet(driver);
auto [target, params] = resources.getRenderPassInfo();
passBuilder.renderFlags(structureRenderFlags);
@@ -751,6 +787,8 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::ssr(FrameGraph& fg,
mSsrPassDescriptorSet.bind(driver);
bindPerRenderableDescriptorSet(driver);
auto const out = resources.getRenderPassInfo();
// Remove the HAS_SHADOWING RenderFlags, since it's irrelevant when rendering reflections
@@ -918,6 +956,7 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::screenSpaceAmbientOcclusion(
[=](FrameGraphResources const& resources, auto const& data, DriverApi& driver) {
// bind the per-view descriptorSet that is used for the structure pass
getStructureDescriptorSet().bind(driver);
bindPerRenderableDescriptorSet(driver);
auto depth = resources.getTexture(data.depth);
auto ssao = resources.getRenderPassInfo();
@@ -1112,6 +1151,7 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::bilateralBlurPass(FrameGraph
auto const& data, DriverApi& driver) {
// TODO: the structure descriptor set might not be the best fit.
getStructureDescriptorSet().bind(driver);
bindPerRenderableDescriptorSet(driver);
auto ssao = resources.getTexture(data.input);
auto blurred = resources.getRenderPassInfo();
@@ -1278,6 +1318,7 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::gaussianBlurPass(FrameGraph&
[=](FrameGraphResources const& resources,
auto const& data, DriverApi& driver) {
bindPostProcessDescriptorSet(driver);
bindPerRenderableDescriptorSet(driver);
// don't use auto for those, b/c the ide can't resolve them
using FGTD = FrameGraphTexture::Descriptor;
@@ -1754,6 +1795,8 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::dof(FrameGraph& fg,
},
[=](FrameGraphResources const& resources, auto const& data, DriverApi& driver) {
bindPostProcessDescriptorSet(driver);
bindPerRenderableDescriptorSet(driver);
auto const& out = resources.getRenderPassInfo();
auto color = resources.getTexture(data.color);
auto depth = resources.getTexture(data.depth);
@@ -1813,6 +1856,7 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::dof(FrameGraph& fg,
[=](FrameGraphResources const& resources,
auto const& data, DriverApi& driver) {
bindPostProcessDescriptorSet(driver);
bindPerRenderableDescriptorSet(driver);
auto desc = resources.getDescriptor(data.inOutColor);
auto inOutColor = resources.getTexture(data.inOutColor);
@@ -1890,6 +1934,7 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::dof(FrameGraph& fg,
[=](FrameGraphResources const& resources,
auto const& data, DriverApi& driver) {
bindPostProcessDescriptorSet(driver);
bindPerRenderableDescriptorSet(driver);
auto const& inputDesc = resources.getDescriptor(data.inCocMinMax);
auto const& out = resources.getRenderPassInfo();
auto inCocMinMax = resources.getTexture(data.inCocMinMax);
@@ -1927,6 +1972,8 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::dof(FrameGraph& fg,
[=](FrameGraphResources const& resources,
auto const& data, DriverApi& driver) {
bindPostProcessDescriptorSet(driver);
bindPerRenderableDescriptorSet(driver);
auto const& out = resources.getRenderPassInfo();
auto inTilesCocMinMax = resources.getTexture(data.inTilesCocMinMax);
auto const& material = getPostProcessMaterial("dofDilate");
@@ -1981,6 +2028,8 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::dof(FrameGraph& fg,
},
[=](FrameGraphResources const& resources, auto const& data, DriverApi& driver) {
bindPostProcessDescriptorSet(driver);
bindPerRenderableDescriptorSet(driver);
auto const& out = resources.getRenderPassInfo();
auto color = resources.getTexture(data.color);
@@ -2045,6 +2094,8 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::dof(FrameGraph& fg,
},
[=](FrameGraphResources const& resources, auto const& data, DriverApi& driver) {
bindPostProcessDescriptorSet(driver);
bindPerRenderableDescriptorSet(driver);
auto const& out = resources.getRenderPassInfo();
auto inColor = resources.getTexture(data.inColor);
@@ -2093,6 +2144,8 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::dof(FrameGraph& fg,
[=](FrameGraphResources const& resources,
auto const& data, DriverApi& driver) {
bindPostProcessDescriptorSet(driver);
bindPerRenderableDescriptorSet(driver);
auto const& out = resources.getRenderPassInfo();
auto color = resources.getTexture(data.color);
@@ -2130,6 +2183,8 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::downscalePass(FrameGraph& fg
[=](FrameGraphResources const& resources,
auto const& data, DriverApi& driver) {
bindPostProcessDescriptorSet(driver);
bindPerRenderableDescriptorSet(driver);
auto const& out = resources.getRenderPassInfo();
auto const& material = getPostProcessMaterial("bloomDownsample2x");
FMaterialInstance* const mi = getMaterialInstance(mEngine, material);
@@ -2263,6 +2318,7 @@ PostProcessManager::BloomPassOutput PostProcessManager::bloom(FrameGraph& fg,
[=](FrameGraphResources const& resources,
auto const& data, DriverApi& driver) {
bindPostProcessDescriptorSet(driver);
bindPerRenderableDescriptorSet(driver);
// TODO: if downsampling is not exactly a multiple of two, use the 13 samples
// filter. This is generally the accepted solution, however, the 13 samples
@@ -2318,6 +2374,7 @@ PostProcessManager::BloomPassOutput PostProcessManager::bloom(FrameGraph& fg,
},
[=](FrameGraphResources const& resources, auto const& data, DriverApi& driver) {
bindPostProcessDescriptorSet(driver);
bindPerRenderableDescriptorSet(driver);
auto hwOut = resources.getTexture(data.out);
auto const& outDesc = resources.getDescriptor(data.out);
@@ -2379,6 +2436,7 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::flarePass(FrameGraph& fg,
[=](FrameGraphResources const& resources,
auto const& data, DriverApi& driver) {
bindPostProcessDescriptorSet(driver);
bindPerRenderableDescriptorSet(driver);
auto in = resources.getTexture(data.in);
auto const out = resources.getRenderPassInfo(0);
const float aspectRatio = float(width) / float(height);
@@ -2457,6 +2515,7 @@ void PostProcessManager::colorGradingSubpass(DriverApi& driver,
ColorGradingConfig const& colorGradingConfig) noexcept {
bindPostProcessDescriptorSet(driver);
bindPerRenderableDescriptorSet(driver);
PostProcessVariant const variant = colorGradingConfig.translucent ?
PostProcessVariant::TRANSLUCENT : PostProcessVariant::OPAQUE;
@@ -2488,6 +2547,7 @@ void PostProcessManager::customResolvePrepareSubpass(DriverApi& driver, CustomRe
void PostProcessManager::customResolveSubpass(DriverApi& driver) noexcept {
bindPostProcessDescriptorSet(driver);
bindPerRenderableDescriptorSet(driver);
FEngine const& engine = mEngine;
Handle<HwRenderPrimitive> const& fullScreenRenderPrimitive = engine.getFullScreenRenderPrimitive();
@@ -2522,6 +2582,7 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::customResolveUncompressPass(
auto out = resources.getRenderPassInfo();
out.params.subpassMask = 1;
bindPostProcessDescriptorSet(driver);
bindPerRenderableDescriptorSet(driver);
driver.beginRenderPass(out.target, out.params);
customResolveSubpass(driver);
driver.endRenderPass();
@@ -2596,6 +2657,7 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::colorGrading(FrameGraph& fg,
},
[=](FrameGraphResources const& resources, auto const& data, DriverApi& driver) {
bindPostProcessDescriptorSet(driver);
bindPerRenderableDescriptorSet(driver);
auto colorTexture = resources.getTexture(data.input);
auto bloomTexture =
@@ -2691,6 +2753,7 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::fxaa(FrameGraph& fg,
},
[=](FrameGraphResources const& resources, auto const& data, DriverApi& driver) {
bindPostProcessDescriptorSet(driver);
bindPerRenderableDescriptorSet(driver);
auto const& inDesc = resources.getDescriptor(data.input);
auto const& texture = resources.getTexture(data.input);
auto const& out = resources.getRenderPassInfo();
@@ -2909,6 +2972,7 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::taa(FrameGraph& fg,
},
[=, &current](FrameGraphResources const& resources, auto const& data, DriverApi& driver) {
bindPostProcessDescriptorSet(driver);
bindPerRenderableDescriptorSet(driver);
constexpr mat4f normalizedToClip{mat4f::row_major_init{
2, 0, 0, -1,
@@ -3051,6 +3115,7 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::rcas(
[=](FrameGraphResources const& resources,
auto const& data, DriverApi& driver) {
bindPostProcessDescriptorSet(driver);
bindPerRenderableDescriptorSet(driver);
auto const input = resources.getTexture(data.input);
auto const out = resources.getRenderPassInfo();
@@ -3122,6 +3187,7 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::upscaleBilinear(FrameGraph&
[this, vp, filter](FrameGraphResources const& resources,
auto const& data, DriverApi& driver) {
bindPostProcessDescriptorSet(driver);
bindPerRenderableDescriptorSet(driver);
auto color = resources.getTexture(data.input);
auto const& inputDesc = resources.getDescriptor(data.input);
@@ -3187,6 +3253,7 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::upscaleSGSR1(FrameGraph& fg,
[this, vp, sourceHasLuminance](FrameGraphResources const& resources,
auto const& data, DriverApi& driver) {
bindPostProcessDescriptorSet(driver);
bindPerRenderableDescriptorSet(driver);
auto color = resources.getTexture(data.input);
auto const& inputDesc = resources.getDescriptor(data.input);
@@ -3274,6 +3341,7 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::upscaleFSR1(FrameGraph& fg,
[this, twoPassesEASU, dsrOptions, vp](FrameGraphResources const& resources,
auto const& data, DriverApi& driver) {
bindPostProcessDescriptorSet(driver);
bindPerRenderableDescriptorSet(driver);
// helper to set the EASU uniforms
auto setEasuUniforms = [vp, backend = mEngine.getBackend()](FMaterialInstance* mi,
@@ -3404,6 +3472,7 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::blit(FrameGraph& fg, bool co
[=](FrameGraphResources const& resources,
auto const& data, DriverApi& driver) {
bindPostProcessDescriptorSet(driver);
bindPerRenderableDescriptorSet(driver);
auto color = resources.getTexture(data.input);
auto const& inputDesc = resources.getDescriptor(data.input);
auto out = resources.getRenderPassInfo();
@@ -3505,6 +3574,7 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::blitDepth(FrameGraph& fg,
},
[=](FrameGraphResources const& resources, auto const& data, DriverApi& driver) {
getStructureDescriptorSet().bind(driver);
bindPerRenderableDescriptorSet(driver);
auto depth = resources.getTexture(data.input);
auto const& inputDesc = resources.getDescriptor(data.input);
auto const out = resources.getRenderPassInfo();
@@ -3623,6 +3693,7 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::resolveDepth(FrameGraph& fg,
},
[=](FrameGraphResources const& resources, auto const& data, DriverApi& driver) {
bindPostProcessDescriptorSet(driver);
bindPerRenderableDescriptorSet(driver);
auto const& input = resources.getTexture(data.input);
auto const& material = getPostProcessMaterial("resolveDepth");
FMaterialInstance* const mi =
@@ -3661,6 +3732,7 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::vsmMipmapPass(FrameGraph& fg
[=](FrameGraphResources const& resources,
auto const& data, DriverApi& driver) {
bindPostProcessDescriptorSet(driver);
bindPerRenderableDescriptorSet(driver);
auto in = driver.createTextureView(resources.getTexture(data.in), level, 1);
auto out = resources.getRenderPassInfo();
@@ -3717,6 +3789,7 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::debugShadowCascades(FrameGra
},
[=](FrameGraphResources const& resources, auto const& data, DriverApi& driver) {
bindPostProcessDescriptorSet(driver);
bindPerRenderableDescriptorSet(driver);
auto color = resources.getTexture(data.color);
auto depth = resources.getTexture(data.depth);
auto const out = resources.getRenderPassInfo();
@@ -3763,6 +3836,7 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::debugCombineArrayTexture(Fra
},
[=](FrameGraphResources const& resources, auto const& data, DriverApi& driver) {
bindPostProcessDescriptorSet(driver);
bindPerRenderableDescriptorSet(driver);
auto color = resources.getTexture(data.input);
auto const& inputDesc = resources.getDescriptor(data.input);
auto out = resources.getRenderPassInfo();
@@ -3845,6 +3919,7 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::debugDisplayShadowTexture(
},
[=](FrameGraphResources const& resources, auto const& data, DriverApi& driver) {
bindPostProcessDescriptorSet(driver);
bindPerRenderableDescriptorSet(driver);
auto const out = resources.getRenderPassInfo();
auto in = resources.getTexture(data.depth);
auto const& material = getPostProcessMaterial("shadowmap");

View File

@@ -395,6 +395,8 @@ public:
private:
static void unbindAllDescriptorSets(backend::DriverApi& driver) noexcept;
void bindPerRenderableDescriptorSet(backend::DriverApi& driver) noexcept;
// Helper to get a MaterialInstance from a FMaterial
// This currently just call FMaterial::getDefaultInstance().
FMaterialInstance* getMaterialInstance(FMaterial const* ma) {
@@ -412,6 +414,11 @@ private:
backend::VertexBufferInfoHandle mFullScreenQuadVbih;
backend::DescriptorSetLayoutHandle mPerRenderableDslh;
// We need to have a dummy descriptor set because each post processing pass is expected to have
// a descriptor set bound at the renderable bind point. But the set itself contains dummy
// values.
backend::DescriptorSetHandle mDummyPerRenderableDsh;
FEngine& mEngine;
mutable SsrPassDescriptorSet mSsrPassDescriptorSet;