This commit is contained in:
Eliza Velasquez
2026-03-09 16:34:29 +09:00
parent c4ea6cb1bf
commit 6b0dc7babe
3 changed files with 89 additions and 60 deletions

View File

@@ -184,13 +184,10 @@ void PostProcessManager::PostProcessMaterial::loadMaterial(FEngine& engine) cons
}
UTILS_NOINLINE
FMaterial* PostProcessManager::PostProcessMaterial::getMaterial(FEngine& engine,
DriverApi& driver, Variant::type_t const variant) const noexcept {
FMaterial* PostProcessManager::PostProcessMaterial::getMaterial(FEngine& engine) const noexcept {
if (UTILS_UNLIKELY(mSize)) {
loadMaterial(engine);
}
mMaterial->getDefaultInstance()->prepareProgram(driver, Variant{ variant },
CompilerPriorityQueue::CRITICAL);
return mMaterial;
}
@@ -248,6 +245,20 @@ void PostProcessManager::bindPerRenderableDescriptorSet(DriverApi& driver) const
{ { 0, 0 }, driver });
}
FMaterialInstance* PostProcessManager::getMaterialInstance(backend::DriverApi& driver,
FMaterial const* ma, Variant::type_t variant) const {
FMaterialInstance* mi = mMaterialInstanceManager.getMaterialInstance(ma);
mi->prepareProgram(driver, Variant{ variant }, backend::CompilerPriorityQueue::CRITICAL);
return mi;
}
FMaterialInstance* PostProcessManager::getMaterialInstanceWithTag(backend::DriverApi& driver,
FMaterial const* ma, uint32_t tag, Variant::type_t variant) const {
FMaterialInstance* mi = mMaterialInstanceManager.getMaterialInstance(ma, tag);
mi->prepareProgram(driver, Variant { variant }, backend::CompilerPriorityQueue::CRITICAL);
return mi;
}
UboManager* PostProcessManager::getUboManager() const noexcept {
return mEngine.getUboManager();
}
@@ -633,8 +644,8 @@ PostProcessManager::StructurePassOutput PostProcessManager::structure(FrameGraph
auto in = resources.getTexture(data.depth);
auto& material = getPostProcessMaterial("mipmapDepth");
FMaterial const* const ma = material.getMaterial(mEngine, driver);
FMaterialInstance* const mi = getMaterialInstance(ma);
FMaterial const* const ma = material.getMaterial(mEngine);
FMaterialInstance* const mi = getMaterialInstance(driver, ma);
// Only the depth texture is changing in the material instance (no UBO updates),
// we do not move getMaterialInstance() inside the loop.
@@ -998,14 +1009,13 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::screenSpaceAmbientOcclusion(
#endif
auto& material = getPostProcessMaterial(materialName);
FMaterial* ma = material.getMaterial(mEngine, driver);
FMaterial* ma = material.getMaterial(mEngine);
ma->getPrograms().setConstants({
{ "useVisibilityBitmasks", options.gtao.useVisibilityBitmasks },
{ "linearThickness", options.gtao.linearThickness },
});
ma = material.getMaterial(mEngine, driver);
FMaterialInstance* const mi = getMaterialInstance(ma);
FMaterialInstance* const mi = getMaterialInstance(driver, ma);
// Set AO type specific material parameters
switch (aoType) {
@@ -1191,8 +1201,8 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::bilateralBlurPass(FrameGraph
auto& material = config.bentNormals ?
getPostProcessMaterial("bilateralBlurBentNormals") :
getPostProcessMaterial("bilateralBlur");
FMaterial const* const ma = material.getMaterial(mEngine, driver);
FMaterialInstance* const mi = getMaterialInstance(ma);
FMaterial const* const ma = material.getMaterial(mEngine);
FMaterialInstance* const mi = getMaterialInstance(driver, ma);
mi->setParameter("ssao", ssao, { /* only reads level 0 */ });
mi->setParameter("axis", axis / float2{desc.width, desc.height});
mi->setParameter("kernel", kGaussianSamples, kGaussianCount);
@@ -1360,7 +1370,7 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::gaussianBlurPass(FrameGraph&
"separableGaussianBlur4L"sv : "separableGaussianBlur4"sv; break;
}
auto const& separableGaussianBlur = getPostProcessMaterial(materialName);
auto ma = separableGaussianBlur.getMaterial(mEngine, driver);
auto ma = separableGaussianBlur.getMaterial(mEngine);
const size_t kernelStorageSize = ma->reflect("kernel")->size;
float2 kernel[64];
@@ -1876,8 +1886,8 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::dof(FrameGraph& fg,
auto inOutCoc = resources.getTexture(data.inOutCoc);
auto const& material = getPostProcessMaterial("dofMipmap");
FMaterial const* const ma = material.getMaterial(mEngine, driver);
FMaterialInstance* const mi = getMaterialInstance(ma);
FMaterial const* const ma = material.getMaterial(mEngine);
FMaterialInstance* const mi = getMaterialInstance(driver, ma);
auto const pipeline = getPipelineState(mi, variant);
@@ -1887,7 +1897,8 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::dof(FrameGraph& fg,
auto const& out = resources.getRenderPassInfo(data.rp[level]);
auto inColor = driver.createTextureView(inOutColor, level, 1);
auto inCoc = driver.createTextureView(inOutCoc, level, 1);
FMaterialInstance* const mi = getMaterialInstance(ma);
// FIXME: is this necessary?
FMaterialInstance* const mi = getMaterialInstance(driver, ma);
mi->setParameter("color", inColor, SamplerParams{
.filterMin = SamplerMinFilter::NEAREST_MIPMAP_NEAREST });
@@ -2404,9 +2415,9 @@ PostProcessManager::BloomPassOutput PostProcessManager::bloom(FrameGraph& fg,
auto const& outDesc = resources.getDescriptor(data.out);
auto const& material = getPostProcessMaterial("bloomUpsample");
FMaterial const* const ma = material.getMaterial(mEngine, driver);
FMaterial const* const ma = material.getMaterial(mEngine);
auto pipeline = getPipelineState(getMaterialInstance(ma));
auto pipeline = getPipelineState(getMaterialInstance(driver, ma));
pipeline.rasterState.blendFunctionSrcRGB = BlendFunction::ONE;
pipeline.rasterState.blendFunctionDstRGB = BlendFunction::ONE;
@@ -2414,7 +2425,7 @@ PostProcessManager::BloomPassOutput PostProcessManager::bloom(FrameGraph& fg,
// Note that we wouldn't want to use the same instance for each pass since that
// would imply using the same UBOs, which implies synchronization across the
// passes.
FMaterialInstance* mi = getMaterialInstance(ma);
FMaterialInstance* mi = getMaterialInstance(driver, ma);
auto hwDstRT = resources.getRenderPassInfo(data.outRT[i - 1]);
hwDstRT.params.flags.discardStart = TargetBufferFlags::NONE; // b/c we'll blend
hwDstRT.params.flags.discardEnd = TargetBufferFlags::NONE;
@@ -2547,9 +2558,10 @@ void PostProcessManager::colorGradingSubpass(DriverApi& driver,
PostProcessVariant::TRANSLUCENT : PostProcessVariant::OPAQUE;
auto const& material = getPostProcessMaterial("colorGradingAsSubpass");
FMaterial const* const ma = material.getMaterial(mEngine, driver, variant);
FMaterial const* const ma = material.getMaterial(mEngine);
// the UBO has been set and committed in colorGradingPrepareSubpass()
FMaterialInstance const* mi = mMaterialInstanceManager.getMaterialInstance(ma, colorGradingConfig.translucent);
FMaterialInstance const* mi =
getMaterialInstanceWithTag(driver, ma, colorGradingConfig.translucent, variant);
mi->use(driver);
auto const pipeline = getPipelineState(mi, variant);
driver.nextSubpass();
@@ -2559,8 +2571,8 @@ void PostProcessManager::colorGradingSubpass(DriverApi& driver,
void PostProcessManager::customResolvePrepareSubpass(DriverApi& driver, CustomResolveOp const op) noexcept {
auto const& material = getPostProcessMaterial("customResolveAsSubpass");
auto const ma = material.getMaterial(mEngine, driver, PostProcessVariant::OPAQUE);
auto* const mi = mMaterialInstanceManager.getMaterialInstance(ma, 0);
auto const ma = material.getMaterial(mEngine);
auto* const mi = getMaterialInstance(driver, ma, 0);
mi->setParameter("direction", op == CustomResolveOp::COMPRESS ? 1.0f : -1.0f),
mi->commit(driver, getUboManager());
}
@@ -2570,9 +2582,9 @@ void PostProcessManager::customResolveSubpass(DriverApi& driver) noexcept {
bindPerRenderableDescriptorSet(driver);
auto const& material = getPostProcessMaterial("customResolveAsSubpass");
FMaterial const* const ma = material.getMaterial(mEngine, driver);
FMaterial const* const ma = material.getMaterial(mEngine);
// the UBO has been set and committed in customResolvePrepareSubpass()
FMaterialInstance const* mi = mMaterialInstanceManager.getMaterialInstance(ma, 0);
FMaterialInstance const* mi = getMaterialInstance(driver, ma, 0);
mi->use(driver);
auto const pipeline = getPipelineState(mi);
@@ -2611,8 +2623,8 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::customResolveUncompressPass(
void PostProcessManager::clearAncillaryBuffersPrepare(DriverApi& driver,
Variant::type_t variant) noexcept {
auto const& material = getPostProcessMaterial("clearDepth");
auto const ma = material.getMaterial(mEngine, driver, variant);
auto const mi = mMaterialInstanceManager.getMaterialInstance(ma, 0);
auto const ma = material.getMaterial(mEngine);
auto const mi = getMaterialInstanceWithTag(driver, ma, 0, variant);
mi->commit(driver, getUboManager());
}
@@ -2627,10 +2639,10 @@ void PostProcessManager::clearAncillaryBuffers(DriverApi& driver,
bindPerRenderableDescriptorSet(driver);
auto const& material = getPostProcessMaterial("clearDepth");
FMaterial const* const ma = material.getMaterial(mEngine, driver, variant);
FMaterial const* const ma = material.getMaterial(mEngine);
// the UBO has been set and committed in clearAncillaryBuffersPrepare()
FMaterialInstance const* const mi = mMaterialInstanceManager.getMaterialInstance(ma, 0);
FMaterialInstance const* const mi = getMaterialInstanceWithTag(driver, ma, 0, variant);
mi->use(driver);
auto pipeline = getPipelineState(mi, variant);
@@ -2643,7 +2655,7 @@ void PostProcessManager::clearAncillaryBuffers(DriverApi& driver,
void PostProcessManager::fogPrepare(DriverApi& driver) noexcept {
// ensures the material is loaded and material instance created
auto const& material = getPostProcessMaterial("fog");
FMaterial const* const ma = material.getMaterial(mEngine, driver, PostProcessVariant::OPAQUE);
FMaterial const* const ma = material.getMaterial(mEngine);
FMaterialInstance const* mi = ma->getDefaultInstance();
mi->commit(driver, getUboManager());
}
@@ -2654,7 +2666,7 @@ void PostProcessManager::fog(DriverApi& driver) noexcept {
bindPerRenderableDescriptorSet(driver);
auto const& material = getPostProcessMaterial("fog");
FMaterial const* const ma = material.getMaterial(mEngine, driver);
FMaterial const* const ma = material.getMaterial(mEngine);
FMaterialInstance const* mi = ma->getDefaultInstance();
mi->use(driver);
@@ -2915,7 +2927,7 @@ void PostProcessManager::TaaJitterCamera(
void PostProcessManager::configureTemporalAntiAliasingMaterial(backend::DriverApi& driver,
TemporalAntiAliasingOptions const& taaOptions) noexcept {
FMaterial* const ma = getPostProcessMaterial("taa").getMaterial(mEngine, driver);
FMaterial* const ma = getPostProcessMaterial("taa").getMaterial(mEngine);
ma->getPrograms().setConstants({
{ "upscaling", taaOptions.upscaling > 1.0f },
{ "historyReprojection", taaOptions.historyReprojection },
@@ -2934,7 +2946,7 @@ FMaterialInstance* PostProcessManager::configureColorGradingMaterial(backend::Dr
PostProcessMaterial const& material, FColorGrading const* colorGrading,
ColorGradingConfig const& colorGradingConfig, VignetteOptions const& vignetteOptions,
uint32_t const width, uint32_t const height) noexcept {
FMaterial* ma = material.getMaterial(mEngine, driver);
FMaterial* ma = material.getMaterial(mEngine);
ma->getPrograms().setConstants({
{ "isOneDimensional", colorGrading->isOneDimensional() },
{ "isLDR", colorGrading->isLDR() },
@@ -2943,8 +2955,9 @@ FMaterialInstance* PostProcessManager::configureColorGradingMaterial(backend::Dr
PostProcessVariant const variant = colorGradingConfig.translucent
? PostProcessVariant::TRANSLUCENT
: PostProcessVariant::OPAQUE;
ma = material.getMaterial(mEngine, driver, variant);
FMaterialInstance* mi = mMaterialInstanceManager.getMaterialInstance(ma, colorGradingConfig.translucent);
ma = material.getMaterial(mEngine);
FMaterialInstance* mi =
getMaterialInstanceWithTag(driver, ma, colorGradingConfig.translucent, variant);
const SamplerParams params = SamplerParams{
.filterMag = SamplerMagFilter::LINEAR,
@@ -3056,9 +3069,9 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::taa(FrameGraph& fg,
PostProcessVariant const variant = colorGradingConfig.translucent ?
PostProcessVariant::TRANSLUCENT : PostProcessVariant::OPAQUE;
FMaterial const* const ma = material.getMaterial(mEngine, driver, variant);
FMaterial const* const ma = material.getMaterial(mEngine);
FMaterialInstance* mi = getMaterialInstance(ma);
FMaterialInstance* mi = getMaterialInstance(driver, ma);
mi->setParameter("color", color, SamplerParams{}); // nearest
mi->setParameter("depth", depth, SamplerParams{}); // nearest
mi->setParameter("history", history, SamplerParams{
@@ -3547,8 +3560,8 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::blit(FrameGraph& fg, bool co
PostProcessMaterial const& material =
getPostProcessMaterial(layer ? "blitArray" : "blitLow");
FMaterial const* const ma = material.getMaterial(mEngine, driver);
auto* mi = getMaterialInstance(ma);
FMaterial const* const ma = material.getMaterial(mEngine);
auto* mi = getMaterialInstance(driver, ma);
mi->setParameter("color", color, SamplerParams{
.filterMag = filterMag,
.filterMin = filterMin
@@ -3806,8 +3819,8 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::vsmMipmapPass(FrameGraph& fg
uint32_t const dim = std::max(1u, width >> (level + 1));
auto& material = getPostProcessMaterial("vsmMipmap");
FMaterial const* const ma = material.getMaterial(mEngine, driver);
FMaterialInstance* const mi = getMaterialInstance(ma);
FMaterial const* const ma = material.getMaterial(mEngine);
FMaterialInstance* const mi = getMaterialInstance(driver, ma);
auto const pipeline = getPipelineState(mi);
backend::Viewport const scissor = { 0, 0, dim, dim };
@@ -3906,10 +3919,10 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::debugCombineArrayTexture(Fra
// set uniforms
PostProcessMaterial const& material = getPostProcessMaterial("blitArray");
FMaterial const* const ma = material.getMaterial(mEngine, driver);
FMaterial const* const ma = material.getMaterial(mEngine);
// It should be ok to not move this getMaterialInstance to inside the loop, since
// this is a pass meant for debug.
auto* mi = getMaterialInstance(ma);
auto* mi = getMaterialInstance(driver, ma);
mi->setParameter("color", color, SamplerParams{
.filterMag = filterMag,
.filterMin = filterMin

View File

@@ -357,13 +357,7 @@ public:
void terminate(FEngine& engine) noexcept;
FMaterial* getMaterial(FEngine& engine, backend::DriverApi& driver,
Variant::type_t variant) const noexcept;
FMaterial* getMaterial(FEngine& engine, backend::DriverApi& driver,
PostProcessVariant variant = PostProcessVariant::OPAQUE) const noexcept {
return getMaterial(engine, driver, Variant::type_t(variant));
}
FMaterial* getMaterial(FEngine& engine) const noexcept;
private:
void loadMaterial(FEngine& engine) const noexcept;
@@ -428,17 +422,37 @@ private:
void bindPerRenderableDescriptorSet(backend::DriverApi& driver) const noexcept;
// Helper to get a MaterialInstance from a FMaterial
// This currently just call FMaterial::getDefaultInstance().
FMaterialInstance* getMaterialInstance(FMaterial const* ma) {
return mMaterialInstanceManager.getMaterialInstance(ma);
// Helpers to get MaterialInstances.
//
// These funcions additionally ensure that the necessary shader programs are compiled via
// prepareProgram().
FMaterialInstance* getMaterialInstance(backend::DriverApi& driver, FMaterial const* ma,
Variant::type_t variant) const;
FMaterialInstance* getMaterialInstance(backend::DriverApi& driver, FMaterial const* ma,
PostProcessVariant variant = PostProcessVariant::OPAQUE) const {
return getMaterialInstance(driver, ma, Variant::type_t(variant));
}
// Helper to get a MaterialInstance from a PostProcessMaterial.
FMaterialInstance* getMaterialInstance(FEngine& engine, backend::DriverApi& driver, PostProcessMaterial const& material,
PostProcessVariant variant = PostProcessVariant::OPAQUE) {
FMaterial const* ma = material.getMaterial(engine, driver, variant);
return getMaterialInstance(ma);
FMaterialInstance* getMaterialInstance(FEngine& engine, backend::DriverApi& driver,
PostProcessMaterial const& material,
PostProcessVariant variant = PostProcessVariant::OPAQUE) const {
return getMaterialInstance(driver, material.getMaterial(engine), Variant::type_t(variant));
}
FMaterialInstance* getMaterialInstanceWithTag(backend::DriverApi& driver, FMaterial const* ma,
uint32_t tag, Variant::type_t variant) const;
FMaterialInstance* getMaterialInstanceWithTag(backend::DriverApi& driver, FMaterial const* ma,
uint32_t tag, PostProcessVariant variant = PostProcessVariant::OPAQUE) const {
return getMaterialInstanceWithTag(driver, ma, tag, Variant::type_t(variant));
}
FMaterialInstance* getMaterialInstanceWithTag(FEngine& engine, backend::DriverApi& driver,
PostProcessMaterial const& material, uint32_t tag,
PostProcessVariant variant = PostProcessVariant::OPAQUE) const {
return getMaterialInstanceWithTag(driver, material.getMaterial(engine), tag,
Variant::type_t(variant));
}
UboManager* getUboManager() const noexcept;

View File

@@ -426,16 +426,18 @@ void RenderPass::setupColorCommand(Command& cmdDraw, Variant variant,
bool const isBlendingCommand = !hasScreenSpaceRefraction &&
(blendingMode != BlendingMode::OPAQUE && blendingMode != BlendingMode::MASKED);
RasterState rasterState = mi->getRasterState();
uint64_t keyDraw = cmdDraw.key;
keyDraw &= ~(PASS_MASK | BLENDING_MASK | MATERIAL_MASK);
keyDraw |= uint64_t(hasScreenSpaceRefraction ? Pass::REFRACT : Pass::COLOR);
keyDraw |= uint64_t(CustomCommand::PASS);
keyDraw |= mi->getSortingKey(); // already all set-up for direct or'ing
keyDraw |= makeField(variant.key, MATERIAL_VARIANT_KEY_MASK, MATERIAL_VARIANT_KEY_SHIFT);
keyDraw |= makeField(ma->getRasterState().alphaToCoverage, BLENDING_MASK, BLENDING_SHIFT);
keyDraw |= makeField(rasterState.alphaToCoverage, BLENDING_MASK, BLENDING_SHIFT);
cmdDraw.key = isBlendingCommand ? keyBlending : keyDraw;
cmdDraw.info.rasterState = mi->getRasterState();
cmdDraw.info.rasterState = rasterState;
// for SSR pass, the blending mode of opaques (including MASKED) must be off
// see Material.cpp.