Skip to content

Commit 16274e3

Browse files
committed
select the proper descriptor set layout in the rendering loop
Now that the per-view layout can be different based on the type of shadow, we need to make sure we set the proper layout in the pipeline and use the corresponding descriptor set. There are now 16 "per-view" layouts and their corresponding descriptor set. There are two sets of 8, the current set is determined by the shadow type on the view. Then during rendering, when we set the pipeline we need to select the corresponding layout; each material now offers both versions of the layout and we just pick the right one.
1 parent 87d5cbc commit 16274e3

File tree

11 files changed

+204
-154
lines changed

11 files changed

+204
-154
lines changed

filament/src/RenderPass.cpp

+13-2
Original file line numberDiff line numberDiff line change
@@ -921,7 +921,6 @@ backend::Viewport RenderPass::Executor::applyScissorViewport(
921921
UTILS_NOINLINE // no need to be inlined
922922
void RenderPass::Executor::execute(FEngine const& engine, DriverApi& driver,
923923
Command const* first, Command const* last) const noexcept {
924-
925924
SYSTRACE_CALL();
926925
SYSTRACE_CONTEXT();
927926

@@ -942,6 +941,13 @@ void RenderPass::Executor::execute(FEngine const& engine, DriverApi& driver,
942941
driver.scissor(mScissor);
943942
}
944943

944+
// If we have a mColorPassDescriptorSet, we need to use its idea of "VSM" to select
945+
// the descriptor set layout. Materials always offer both.
946+
// If we don't have a mColorPassDescriptorSet, it doesn't matter because the layout
947+
// are chosen via the variant only.
948+
bool const useVsmDescriptorSetLayout =
949+
mColorPassDescriptorSet ? mColorPassDescriptorSet->isVSM() : false;
950+
945951
bool const polygonOffsetOverride = mPolygonOffsetOverride;
946952
PipelineState pipeline{
947953
// initialize with polygon offset override
@@ -1051,8 +1057,13 @@ void RenderPass::Executor::execute(FEngine const& engine, DriverApi& driver,
10511057

10521058
// Each material has its own version of the per-view descriptor-set layout,
10531059
// because it depends on the material features (e.g. lit/unlit)
1060+
// TODO: QUESTION: are
1061+
// Variant::isValidDepthVariant(info.materialVariant) and
1062+
// Variant::isSSRVariant(info.materialVariant)
1063+
// constant? If so we could precompute ma->getPerViewDescriptorSetLayout()
10541064
pipeline.pipelineLayout.setLayout[+DescriptorSetBindingPoints::PER_VIEW] =
1055-
ma->getPerViewDescriptorSetLayout(info.materialVariant).getHandle();
1065+
ma->getPerViewDescriptorSetLayout(info.materialVariant,
1066+
useVsmDescriptorSetLayout).getHandle();
10561067

10571068
// Each material has a per-material descriptor-set layout which encodes the
10581069
// material's parameters (ubo and samplers)

filament/src/details/Material.cpp

+27-15
Original file line numberDiff line numberDiff line change
@@ -329,11 +329,12 @@ FMaterial::FMaterial(FEngine& engine, const Builder& builder,
329329

330330
parser->hasCustomDepthShader(&mHasCustomDepthShader);
331331

332-
mPerViewLayoutIndex = ColorPassDescriptorSet::getIndex(
333-
mIsVariantLit,
334-
mReflectionMode == ReflectionMode::SCREEN_SPACE ||
335-
mRefractionMode == RefractionMode::SCREEN_SPACE,
336-
!(mVariantFilterMask & +UserVariantFilterBit::FOG));
332+
bool const isLit = mIsVariantLit || mHasShadowMultiplier;
333+
bool const isSSR = mReflectionMode == ReflectionMode::SCREEN_SPACE ||
334+
mRefractionMode == RefractionMode::SCREEN_SPACE;
335+
bool const hasFog = !(mVariantFilterMask & UserVariantFilterMask(UserVariantFilterBit::FOG));
336+
337+
mPerViewLayoutIndex = ColorPassDescriptorSet::getIndex(isLit, isSSR, hasFog);
337338

338339
processBlendingMode(parser);
339340
processSpecializationConstants(engine, builder, parser);
@@ -407,6 +408,7 @@ void FMaterial::terminate(FEngine& engine) {
407408

408409
DriverApi& driver = engine.getDriverApi();
409410
mPerViewDescriptorSetLayout.terminate(engine.getDescriptorSetLayoutFactory(), driver);
411+
mPerViewDescriptorSetLayoutVsm.terminate(engine.getDescriptorSetLayoutFactory(), driver);
410412
mDescriptorSetLayout.terminate(engine.getDescriptorSetLayoutFactory(), driver);
411413
}
412414

@@ -1149,17 +1151,23 @@ void FMaterial::processDescriptorSets(FEngine& engine, MaterialParser const* con
11491151
backend::DescriptorSetLayout descriptorSetLayout;
11501152
success = parser->getDescriptorSetLayout(&descriptorSetLayout);
11511153
assert_invariant(success);
1152-
auto perMatLabel = mName;
1153-
perMatLabel.append("_perMat");
1154-
descriptorSetLayout.label = std::move(perMatLabel);
11551154

11561155
// get the PER_VIEW descriptor binding info
1157-
auto perViewDescriptorSetLayout =
1158-
descriptor_sets::getPerViewDescriptorSetLayout(mMaterialDomain, mVariantFilterMask,
1159-
mIsVariantLit || mHasShadowMultiplier, mReflectionMode, mRefractionMode);
1160-
auto perViewLabel = mName;
1161-
perViewLabel.append("_perView");
1162-
perViewDescriptorSetLayout.label = std::move(perViewLabel);
1156+
bool const isLit = mIsVariantLit || mHasShadowMultiplier;
1157+
bool const isSSR = mReflectionMode == ReflectionMode::SCREEN_SPACE ||
1158+
mRefractionMode == RefractionMode::SCREEN_SPACE;
1159+
bool const hasFog = !(mVariantFilterMask & UserVariantFilterMask(UserVariantFilterBit::FOG));
1160+
1161+
auto perViewDescriptorSetLayout = descriptor_sets::getPerViewDescriptorSetLayout(
1162+
mMaterialDomain, isLit, isSSR, hasFog, false);
1163+
1164+
auto perViewDescriptorSetLayoutVsm = descriptor_sets::getPerViewDescriptorSetLayout(
1165+
mMaterialDomain, isLit, isSSR, hasFog, true);
1166+
1167+
// set the labels
1168+
descriptorSetLayout.label = CString{ mName }.append("_perMat");
1169+
perViewDescriptorSetLayout.label = CString{ mName }.append("_perView");
1170+
perViewDescriptorSetLayoutVsm.label = CString{ mName }.append("_perViewVsm");
11631171

11641172
// get the PER_RENDERABLE and PER_VIEW descriptor binding info
11651173
for (auto&& [bindingPoint, descriptorSetLayout] : {
@@ -1181,7 +1189,11 @@ void FMaterial::processDescriptorSets(FEngine& engine, MaterialParser const* con
11811189

11821190
mPerViewDescriptorSetLayout = {
11831191
engine.getDescriptorSetLayoutFactory(),
1184-
engine.getDriverApi(), perViewDescriptorSetLayout };
1192+
engine.getDriverApi(), std::move(perViewDescriptorSetLayout) };
1193+
1194+
mPerViewDescriptorSetLayoutVsm = {
1195+
engine.getDescriptorSetLayoutFactory(),
1196+
engine.getDriverApi(), std::move(perViewDescriptorSetLayoutVsm) };
11851197
}
11861198

11871199
descriptor_binding_t FMaterial::getSamplerBinding(

filament/src/details/Material.h

+7-1
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,8 @@ class FMaterial : public Material {
9393
return mPerViewDescriptorSetLayout;
9494
}
9595

96-
DescriptorSetLayout const& getPerViewDescriptorSetLayout(Variant const variant) const noexcept {
96+
DescriptorSetLayout const& getPerViewDescriptorSetLayout(
97+
Variant const variant, bool const useVsmDescriptorSetLayout) const noexcept {
9798
if (Variant::isValidDepthVariant(variant)) {
9899
assert_invariant(mMaterialDomain == MaterialDomain::SURFACE);
99100
return mEngine.getPerViewDescriptorSetLayoutDepthVariant();
@@ -102,6 +103,10 @@ class FMaterial : public Material {
102103
assert_invariant(mMaterialDomain == MaterialDomain::SURFACE);
103104
return mEngine.getPerViewDescriptorSetLayoutSsrVariant();
104105
}
106+
if (useVsmDescriptorSetLayout) {
107+
assert_invariant(mMaterialDomain == MaterialDomain::SURFACE);
108+
return mPerViewDescriptorSetLayoutVsm;
109+
}
105110
return mPerViewDescriptorSetLayout;
106111
}
107112

@@ -312,6 +317,7 @@ class FMaterial : public Material {
312317
// try to order by frequency of use
313318
mutable std::array<backend::Handle<backend::HwProgram>, VARIANT_COUNT> mCachedPrograms;
314319
DescriptorSetLayout mPerViewDescriptorSetLayout;
320+
DescriptorSetLayout mPerViewDescriptorSetLayoutVsm;
315321
DescriptorSetLayout mDescriptorSetLayout;
316322
backend::Program::DescriptorSetInfo mProgramDescriptorBindings;
317323

filament/src/details/View.cpp

+38-31
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,10 @@ FView::FView(FEngine& engine)
6868
mFogEntity(engine.getEntityManager().create()),
6969
mIsStereoSupported(engine.getDriverApi().isStereoSupported()),
7070
mUniforms(engine.getDriverApi()),
71-
mColorPassDescriptorSet(engine, mUniforms) {
72-
71+
mColorPassDescriptorSet{
72+
{ engine, false, mUniforms },
73+
{ engine, true, mUniforms } }
74+
{
7375
DriverApi& driver = engine.getDriverApi();
7476

7577
FDebugRegistry& debugRegistry = engine.getDebugRegistry();
@@ -125,11 +127,13 @@ FView::FView(FEngine& engine)
125127

126128
mDefaultColorGrading = mColorGrading = engine.getDefaultColorGrading();
127129

128-
mColorPassDescriptorSet.init(
129-
engine,
130-
mLightUbh,
131-
mFroxelizer.getRecordBuffer(),
132-
mFroxelizer.getFroxelBuffer());
130+
for (auto&& colorPassDescriptorSet : mColorPassDescriptorSet) {
131+
colorPassDescriptorSet.init(
132+
engine,
133+
mLightUbh,
134+
mFroxelizer.getRecordBuffer(),
135+
mFroxelizer.getFroxelBuffer());
136+
}
133137
}
134138

135139
FView::~FView() noexcept = default;
@@ -146,7 +150,9 @@ void FView::terminate(FEngine& engine) {
146150

147151
ShadowMapManager::terminate(engine, mShadowMapManager);
148152
mUniforms.terminate(driver);
149-
mColorPassDescriptorSet.terminate(engine.getDescriptorSetLayoutFactory(), driver);
153+
for (auto&& colorPassDescriptorSet : mColorPassDescriptorSet) {
154+
colorPassDescriptorSet.terminate(engine.getDescriptorSetLayoutFactory(), driver);
155+
}
150156
mFroxelizer.terminate(driver);
151157
mCommonRenderableDescriptorSet.terminate(driver);
152158

@@ -429,7 +435,7 @@ void FView::prepareLighting(FEngine& engine, CameraInfo const& cameraInfo) noexc
429435
*/
430436

431437
const float exposure = Exposure::exposure(cameraInfo.ev100);
432-
mColorPassDescriptorSet.prepareExposure(cameraInfo.ev100);
438+
getColorPassDescriptorSet().prepareExposure(cameraInfo.ev100);
433439

434440
/*
435441
* Indirect light (IBL)
@@ -446,15 +452,15 @@ void FView::prepareLighting(FEngine& engine, CameraInfo const& cameraInfo) noexc
446452
FSkybox const* const skybox = scene->getSkybox();
447453
intensity = skybox ? skybox->getIntensity() : FIndirectLight::DEFAULT_INTENSITY;
448454
}
449-
mColorPassDescriptorSet.prepareAmbientLight(engine, *ibl, intensity, exposure);
455+
getColorPassDescriptorSet().prepareAmbientLight(engine, *ibl, intensity, exposure);
450456

451457
/*
452458
* Directional light (always at index 0)
453459
*/
454460

455461
FLightManager::Instance const directionalLight = lightData.elementAt<FScene::LIGHT_INSTANCE>(0);
456462
const float3 sceneSpaceDirection = lightData.elementAt<FScene::DIRECTION>(0); // guaranteed normalized
457-
mColorPassDescriptorSet.prepareDirectionalLight(engine, exposure, sceneSpaceDirection, directionalLight);
463+
getColorPassDescriptorSet().prepareDirectionalLight(engine, exposure, sceneSpaceDirection, directionalLight);
458464
}
459465

460466
CameraInfo FView::computeCameraInfo(FEngine& engine) const noexcept {
@@ -606,7 +612,7 @@ void FView::prepare(FEngine& engine, DriverApi& driver, RootArenaScope& rootAren
606612
cameraInfo.projection, cameraInfo.zn, cameraInfo.zf)) {
607613
// TODO: might be more consistent to do this in prepareLighting(), but it's not
608614
// strictly necessary
609-
mColorPassDescriptorSet.prepareDynamicLights(mFroxelizer);
615+
getColorPassDescriptorSet().prepareDynamicLights(mFroxelizer);
610616
}
611617
// We need to pass viewMatrix by value here because it extends the scope of this
612618
// function.
@@ -797,12 +803,13 @@ void FView::prepare(FEngine& engine, DriverApi& driver, RootArenaScope& rootAren
797803
auto const& tcm = engine.getTransformManager();
798804
auto const fogTransform = tcm.getWorldTransformAccurate(tcm.getInstance(mFogEntity));
799805

800-
mColorPassDescriptorSet.prepareTime(engine, userTime);
801-
mColorPassDescriptorSet.prepareFog(engine, cameraInfo, fogTransform, mFogOptions,
806+
auto& colorPassDescriptorSet = getColorPassDescriptorSet();
807+
colorPassDescriptorSet.prepareTime(engine, userTime);
808+
colorPassDescriptorSet.prepareFog(engine, cameraInfo, fogTransform, mFogOptions,
802809
scene->getIndirectLight());
803-
mColorPassDescriptorSet.prepareTemporalNoise(engine, mTemporalAntiAliasingOptions);
804-
mColorPassDescriptorSet.prepareBlending(needsAlphaChannel);
805-
mColorPassDescriptorSet.prepareMaterialGlobals(mMaterialGlobals);
810+
colorPassDescriptorSet.prepareTemporalNoise(engine, mTemporalAntiAliasingOptions);
811+
colorPassDescriptorSet.prepareBlending(needsAlphaChannel);
812+
colorPassDescriptorSet.prepareMaterialGlobals(mMaterialGlobals);
806813
}
807814

808815
void FView::computeVisibilityMasks(
@@ -863,12 +870,12 @@ void FView::prepareUpscaler(float2 const scale,
863870
derivativesScale = 0.5f;
864871
}
865872
}
866-
mColorPassDescriptorSet.prepareLodBias(bias, derivativesScale);
873+
getColorPassDescriptorSet().prepareLodBias(bias, derivativesScale);
867874
}
868875

869876
void FView::prepareCamera(FEngine& engine, const CameraInfo& cameraInfo) const noexcept {
870877
SYSTRACE_CALL();
871-
mColorPassDescriptorSet.prepareCamera(engine, cameraInfo);
878+
getColorPassDescriptorSet().prepareCamera(engine, cameraInfo);
872879
}
873880

874881
void FView::prepareViewport(
@@ -877,23 +884,23 @@ void FView::prepareViewport(
877884
SYSTRACE_CALL();
878885
// TODO: we should pass viewport.{left|bottom} to the backend, so it can offset the
879886
// scissor properly.
880-
mColorPassDescriptorSet.prepareViewport(physicalViewport, logicalViewport);
887+
getColorPassDescriptorSet().prepareViewport(physicalViewport, logicalViewport);
881888
}
882889

883890
void FView::prepareSSAO(Handle<HwTexture> ssao) const noexcept {
884-
mColorPassDescriptorSet.prepareSSAO(ssao, mAmbientOcclusionOptions);
891+
getColorPassDescriptorSet().prepareSSAO(ssao, mAmbientOcclusionOptions);
885892
}
886893

887894
void FView::prepareSSR(Handle<HwTexture> ssr,
888895
bool const disableSSR,
889896
float const refractionLodOffset,
890897
ScreenSpaceReflectionsOptions const& ssrOptions) const noexcept {
891-
mColorPassDescriptorSet.prepareSSR(ssr, disableSSR, refractionLodOffset, ssrOptions);
898+
getColorPassDescriptorSet().prepareSSR(ssr, disableSSR, refractionLodOffset, ssrOptions);
892899
}
893900

894901
void FView::prepareStructure(Handle<HwTexture> structure) const noexcept {
895902
// sampler must be NEAREST
896-
mColorPassDescriptorSet.prepareStructure(structure);
903+
getColorPassDescriptorSet().prepareStructure(structure);
897904
}
898905

899906
void FView::prepareShadow(Handle<HwTexture> texture) const noexcept {
@@ -905,37 +912,37 @@ void FView::prepareShadow(Handle<HwTexture> texture) const noexcept {
905912
}
906913
switch (mShadowType) {
907914
case ShadowType::PCF:
908-
mColorPassDescriptorSet.prepareShadowPCF(texture, uniforms);
915+
getColorPassDescriptorSet().prepareShadowPCF(texture, uniforms);
909916
break;
910917
case ShadowType::VSM:
911-
mColorPassDescriptorSet.prepareShadowVSM(texture, uniforms, mVsmShadowOptions);
918+
getColorPassDescriptorSet().prepareShadowVSM(texture, uniforms, mVsmShadowOptions);
912919
break;
913920
case ShadowType::DPCF:
914-
mColorPassDescriptorSet.prepareShadowDPCF(texture, uniforms, mSoftShadowOptions);
921+
getColorPassDescriptorSet().prepareShadowDPCF(texture, uniforms, mSoftShadowOptions);
915922
break;
916923
case ShadowType::PCSS:
917-
mColorPassDescriptorSet.prepareShadowPCSS(texture, uniforms, mSoftShadowOptions);
924+
getColorPassDescriptorSet().prepareShadowPCSS(texture, uniforms, mSoftShadowOptions);
918925
break;
919926
case ShadowType::PCFd:
920-
mColorPassDescriptorSet.prepareShadowPCFDebug(texture, uniforms);
927+
getColorPassDescriptorSet().prepareShadowPCFDebug(texture, uniforms);
921928
break;
922929
}
923930
}
924931

925932
void FView::prepareShadowMapping(bool const highPrecision) const noexcept {
926933
if (mHasShadowing) {
927934
assert_invariant(mShadowMapManager);
928-
mColorPassDescriptorSet.prepareShadowMapping(
935+
getColorPassDescriptorSet().prepareShadowMapping(
929936
mShadowMapManager->getShadowUniformsHandle(), highPrecision);
930937
}
931938
}
932939

933940
void FView::commitUniformsAndSamplers(DriverApi& driver) const noexcept {
934-
mColorPassDescriptorSet.commit(driver);
941+
getColorPassDescriptorSet().commit(driver);
935942
}
936943

937944
void FView::unbindSamplers(DriverApi& driver) noexcept {
938-
mColorPassDescriptorSet.unbindSamplers(driver);
945+
getColorPassDescriptorSet().unbindSamplers(driver);
939946
}
940947

941948
void FView::commitFroxels(DriverApi& driverApi) const noexcept {

filament/src/details/View.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -440,7 +440,9 @@ class FView : public View {
440440
static void cullRenderables(utils::JobSystem& js, FScene::RenderableSoa& renderableData,
441441
Frustum const& frustum, size_t bit) noexcept;
442442

443-
ColorPassDescriptorSet& getColorPassDescriptorSet() noexcept { return mColorPassDescriptorSet; }
443+
ColorPassDescriptorSet& getColorPassDescriptorSet() const noexcept {
444+
return mColorPassDescriptorSet[mShadowType == ShadowType::PCF ? 0 : 1];
445+
}
444446

445447
// Returns the frame history FIFO. This is typically used by the FrameGraph to access
446448
// previous frame data.
@@ -587,7 +589,7 @@ class FView : public View {
587589
RenderQuality mRenderQuality;
588590

589591
mutable TypedUniformBuffer<PerViewUib> mUniforms;
590-
mutable ColorPassDescriptorSet mColorPassDescriptorSet;
592+
mutable ColorPassDescriptorSet mColorPassDescriptorSet[2];
591593

592594
mutable FrameHistory mFrameHistory{};
593595

filament/src/ds/ColorPassDescriptorSet.cpp

+5-14
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ uint8_t ColorPassDescriptorSet::getIndex(
7979
index |= 0x2;
8080
}
8181

82-
if (!fog) {
82+
if (fog) {
8383
// this will remove samplers needed for fog
8484
index |= 0x4;
8585
}
@@ -88,27 +88,18 @@ uint8_t ColorPassDescriptorSet::getIndex(
8888
return index;
8989
}
9090

91-
92-
ColorPassDescriptorSet::ColorPassDescriptorSet(FEngine& engine,
91+
ColorPassDescriptorSet::ColorPassDescriptorSet(FEngine& engine, bool const vsm,
9392
TypedUniformBuffer<PerViewUib>& uniforms) noexcept
94-
: mUniforms(uniforms) {
95-
96-
constexpr UserVariantFilterMask filterFog = UserVariantFilterMask(UserVariantFilterBit::FOG);
97-
constexpr UserVariantFilterMask keepFog = UserVariantFilterMask(0);
98-
93+
: mUniforms(uniforms), mIsVsm(vsm) {
9994
for (bool const lit: { false, true }) {
10095
for (bool const ssr: { false, true }) {
10196
for (bool const fog: { false, true }) {
102-
auto index = getIndex(lit, ssr, fog);
97+
auto const index = getIndex(lit, ssr, fog);
10398
mDescriptorSetLayout[index] = {
10499
engine.getDescriptorSetLayoutFactory(),
105100
engine.getDriverApi(),
106101
descriptor_sets::getPerViewDescriptorSetLayout(
107-
MaterialDomain::SURFACE,
108-
fog ? keepFog : filterFog,
109-
lit,
110-
ssr ? ReflectionMode::SCREEN_SPACE : ReflectionMode::DEFAULT,
111-
ssr ? RefractionMode::SCREEN_SPACE : RefractionMode::NONE)
102+
MaterialDomain::SURFACE, lit, ssr, fog, vsm)
112103
};
113104
mDescriptorSet[index] = DescriptorSet{ mDescriptorSetLayout[index] };
114105
}

0 commit comments

Comments
 (0)