Compare commits
2 Commits
pf/delay-d
...
pf/renderd
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e4fa86fb01 | ||
|
|
7da2a08df6 |
@@ -271,8 +271,8 @@ std::unique_ptr<MaterialDefinition> MaterialDefinition::create(FEngine& engine,
|
|||||||
|
|
||||||
void MaterialDefinition::terminate(FEngine& engine) {
|
void MaterialDefinition::terminate(FEngine& engine) {
|
||||||
DriverApi& driver = engine.getDriverApi();
|
DriverApi& driver = engine.getDriverApi();
|
||||||
perViewDescriptorSetLayout.terminate(engine.getDescriptorSetLayoutFactory(), driver);
|
perViewDescriptorSetLayoutPcf.terminate(engine.getDescriptorSetLayoutFactory(), driver);
|
||||||
perViewDescriptorSetLayoutVsm.terminate(engine.getDescriptorSetLayoutFactory(), driver);
|
perViewDescriptorSetLayoutS2d.terminate(engine.getDescriptorSetLayoutFactory(), driver);
|
||||||
descriptorSetLayout.terminate(engine.getDescriptorSetLayoutFactory(), driver);
|
descriptorSetLayout.terminate(engine.getDescriptorSetLayoutFactory(), driver);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -607,23 +607,23 @@ void MaterialDefinition::processDescriptorSets(FEngine& engine) {
|
|||||||
refractionMode == RefractionMode::SCREEN_SPACE;
|
refractionMode == RefractionMode::SCREEN_SPACE;
|
||||||
bool const hasFog = !(variantFilterMask & UserVariantFilterMask(UserVariantFilterBit::FOG));
|
bool const hasFog = !(variantFilterMask & UserVariantFilterMask(UserVariantFilterBit::FOG));
|
||||||
|
|
||||||
this->perViewDescriptorSetLayoutDescription = descriptor_sets::getPerViewDescriptorSetLayout(
|
this->perViewDescriptorSetLayoutPcfDescription = descriptor_sets::getPerViewDescriptorSetLayout(
|
||||||
materialDomain, isLit, isSSR, hasFog, false);
|
materialDomain, isLit, isSSR, hasFog, false);
|
||||||
|
|
||||||
this->perViewDescriptorSetLayoutVsmDescription = descriptor_sets::getPerViewDescriptorSetLayout(
|
this->perViewDescriptorSetLayoutS2dDescription = descriptor_sets::getPerViewDescriptorSetLayout(
|
||||||
materialDomain, isLit, isSSR, hasFog, true);
|
materialDomain, isLit, isSSR, hasFog, true);
|
||||||
|
|
||||||
// set the labels
|
// set the labels
|
||||||
this->descriptorSetLayoutDescription.label = CString{ name }.append("_perMat");
|
this->descriptorSetLayoutDescription.label = CString{ name }.append("_perMat");
|
||||||
this->perViewDescriptorSetLayoutDescription.label = CString{ name }.append("_perView");
|
this->perViewDescriptorSetLayoutPcfDescription.label = CString{ name }.append("_perView");
|
||||||
this->perViewDescriptorSetLayoutVsmDescription.label = CString{ name }.append("_perViewVsm");
|
this->perViewDescriptorSetLayoutS2dDescription.label = CString{ name }.append("_perViewVsm");
|
||||||
|
|
||||||
// get the PER_RENDERABLE and PER_VIEW descriptor binding info
|
// get the PER_RENDERABLE and PER_VIEW descriptor binding info
|
||||||
for (auto&& [bindingPoint, dsl] : {
|
for (auto&& [bindingPoint, dsl] : {
|
||||||
std::pair{ DescriptorSetBindingPoints::PER_RENDERABLE,
|
std::pair{ DescriptorSetBindingPoints::PER_RENDERABLE,
|
||||||
descriptor_sets::getPerRenderableLayout() },
|
descriptor_sets::getPerRenderableLayout() },
|
||||||
std::pair{ DescriptorSetBindingPoints::PER_VIEW,
|
std::pair{ DescriptorSetBindingPoints::PER_VIEW,
|
||||||
this->perViewDescriptorSetLayoutDescription }}) {
|
this->perViewDescriptorSetLayoutPcfDescription }}) {
|
||||||
Program::DescriptorBindingsInfo& descriptors = programDescriptorBindings[+bindingPoint];
|
Program::DescriptorBindingsInfo& descriptors = programDescriptorBindings[+bindingPoint];
|
||||||
descriptors.reserve(dsl.descriptors.size());
|
descriptors.reserve(dsl.descriptors.size());
|
||||||
for (auto const& entry: dsl.descriptors) {
|
for (auto const& entry: dsl.descriptors) {
|
||||||
@@ -636,17 +636,17 @@ void MaterialDefinition::processDescriptorSets(FEngine& engine) {
|
|||||||
descriptorSetLayoutFactory, driver,
|
descriptorSetLayoutFactory, driver,
|
||||||
this->descriptorSetLayoutDescription };
|
this->descriptorSetLayoutDescription };
|
||||||
|
|
||||||
this->perViewDescriptorSetLayout = {
|
this->perViewDescriptorSetLayoutPcf = {
|
||||||
descriptorSetLayoutFactory, driver,
|
descriptorSetLayoutFactory, driver,
|
||||||
this->perViewDescriptorSetLayoutDescription };
|
this->perViewDescriptorSetLayoutPcfDescription };
|
||||||
|
|
||||||
this->perViewDescriptorSetLayoutVsm = {
|
this->perViewDescriptorSetLayoutS2d = {
|
||||||
descriptorSetLayoutFactory, driver,
|
descriptorSetLayoutFactory, driver,
|
||||||
this->perViewDescriptorSetLayoutVsmDescription };
|
this->perViewDescriptorSetLayoutS2dDescription };
|
||||||
}
|
}
|
||||||
|
|
||||||
backend::DescriptorSetLayout const& MaterialDefinition::getPerViewDescriptorSetLayoutDescription(
|
backend::DescriptorSetLayout const& MaterialDefinition::getPerViewDescriptorSetLayoutDescription(
|
||||||
Variant const variant, bool const useVsmDescriptorSetLayout) const noexcept {
|
Variant const variant, bool const useS2dDescriptorSetLayout) const noexcept {
|
||||||
if (materialDomain == MaterialDomain::SURFACE) {
|
if (materialDomain == MaterialDomain::SURFACE) {
|
||||||
if (Variant::isValidDepthVariant(variant)) {
|
if (Variant::isValidDepthVariant(variant)) {
|
||||||
// Use the layout description used to create the per view depth variant layout.
|
// Use the layout description used to create the per view depth variant layout.
|
||||||
@@ -657,10 +657,10 @@ backend::DescriptorSetLayout const& MaterialDefinition::getPerViewDescriptorSetL
|
|||||||
return descriptor_sets::getSsrVariantLayout();
|
return descriptor_sets::getSsrVariantLayout();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (useVsmDescriptorSetLayout) {
|
if (useS2dDescriptorSetLayout) {
|
||||||
return perViewDescriptorSetLayoutVsmDescription;
|
return perViewDescriptorSetLayoutS2dDescription;
|
||||||
}
|
}
|
||||||
return perViewDescriptorSetLayoutDescription;
|
return perViewDescriptorSetLayoutPcfDescription;
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle<HwProgram> MaterialDefinition::compileProgram(
|
Handle<HwProgram> MaterialDefinition::compileProgram(
|
||||||
@@ -689,7 +689,7 @@ Handle<HwProgram> MaterialDefinition::compileProgram(
|
|||||||
pb.descriptorLayout(+DescriptorSetBindingPoints::PER_VIEW,
|
pb.descriptorLayout(+DescriptorSetBindingPoints::PER_VIEW,
|
||||||
getPerViewDescriptorSetLayoutDescription(
|
getPerViewDescriptorSetLayoutDescription(
|
||||||
specialization.variant,
|
specialization.variant,
|
||||||
Variant::isVSMVariant(specialization.variant)));
|
Variant::isShadowSampler2DVariant(specialization.variant)));
|
||||||
pb.descriptorLayout(+DescriptorSetBindingPoints::PER_RENDERABLE,
|
pb.descriptorLayout(+DescriptorSetBindingPoints::PER_RENDERABLE,
|
||||||
descriptor_sets::getPerRenderableLayout());
|
descriptor_sets::getPerRenderableLayout());
|
||||||
pb.descriptorLayout(
|
pb.descriptorLayout(
|
||||||
|
|||||||
@@ -94,17 +94,17 @@ struct MaterialDefinition {
|
|||||||
backend::ShaderModel const sm, bool isStereoSupported) const noexcept;
|
backend::ShaderModel const sm, bool isStereoSupported) const noexcept;
|
||||||
|
|
||||||
backend::DescriptorSetLayout const& getPerViewDescriptorSetLayoutDescription(
|
backend::DescriptorSetLayout const& getPerViewDescriptorSetLayoutDescription(
|
||||||
Variant const variant, bool useVsmDescriptorSetLayout) const noexcept;
|
Variant const variant, bool useS2dDescriptorSetLayout) const noexcept;
|
||||||
|
|
||||||
// Keep track of the definitions of the descriptor set layouts, as these
|
// Keep track of the definitions of the descriptor set layouts, as these
|
||||||
// may be used by some backends in parallel compilation of programs.
|
// may be used by some backends in parallel compilation of programs.
|
||||||
backend::DescriptorSetLayout perViewDescriptorSetLayoutDescription;
|
backend::DescriptorSetLayout perViewDescriptorSetLayoutPcfDescription;
|
||||||
backend::DescriptorSetLayout perViewDescriptorSetLayoutVsmDescription;
|
backend::DescriptorSetLayout perViewDescriptorSetLayoutS2dDescription;
|
||||||
backend::DescriptorSetLayout descriptorSetLayoutDescription;
|
backend::DescriptorSetLayout descriptorSetLayoutDescription;
|
||||||
|
|
||||||
// try to order by frequency of use
|
// try to order by frequency of use
|
||||||
filament::DescriptorSetLayout perViewDescriptorSetLayout;
|
filament::DescriptorSetLayout perViewDescriptorSetLayoutPcf;
|
||||||
filament::DescriptorSetLayout perViewDescriptorSetLayoutVsm;
|
filament::DescriptorSetLayout perViewDescriptorSetLayoutS2d;
|
||||||
filament::DescriptorSetLayout descriptorSetLayout;
|
filament::DescriptorSetLayout descriptorSetLayout;
|
||||||
backend::Program::DescriptorSetInfo programDescriptorBindings;
|
backend::Program::DescriptorSetInfo programDescriptorBindings;
|
||||||
|
|
||||||
|
|||||||
@@ -802,7 +802,7 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::ssr(FrameGraph& fg,
|
|||||||
|
|
||||||
// use our special SSR variant, it can only be applied to object that have
|
// use our special SSR variant, it can only be applied to object that have
|
||||||
// the SCREEN_SPACE ReflectionMode.
|
// the SCREEN_SPACE ReflectionMode.
|
||||||
passBuilder.variant(Variant{ Variant::SPECIAL_SSR });
|
passBuilder.variant(Variant{ Variant::SPECIAL_SSR_VARIANT });
|
||||||
|
|
||||||
// generate all our drawing commands, except blended objects.
|
// generate all our drawing commands, except blended objects.
|
||||||
passBuilder.commandTypeFlags(RenderPass::CommandTypeFlags::SCREEN_SPACE_REFLECTIONS);
|
passBuilder.commandTypeFlags(RenderPass::CommandTypeFlags::SCREEN_SPACE_REFLECTIONS);
|
||||||
|
|||||||
@@ -568,7 +568,7 @@ RenderPass::Command* RenderPass::generateCommandsImpl(CommandTypeFlags extraFlag
|
|||||||
if constexpr (isDepthPass) {
|
if constexpr (isDepthPass) {
|
||||||
cmd.info.materialVariant = variant;
|
cmd.info.materialVariant = variant;
|
||||||
cmd.info.rasterState = {};
|
cmd.info.rasterState = {};
|
||||||
cmd.info.rasterState.colorWrite = Variant::isPickingVariant(variant) || Variant::isVSMVariant(variant);
|
cmd.info.rasterState.colorWrite = Variant::isPickingVariant(variant) || Variant::isDepthMomentsVariant(variant);
|
||||||
cmd.info.rasterState.depthWrite = true;
|
cmd.info.rasterState.depthWrite = true;
|
||||||
cmd.info.rasterState.depthFunc = RasterState::DepthFunc::GE;
|
cmd.info.rasterState.depthFunc = RasterState::DepthFunc::GE;
|
||||||
cmd.info.rasterState.alphaToCoverage = false;
|
cmd.info.rasterState.alphaToCoverage = false;
|
||||||
@@ -616,7 +616,7 @@ RenderPass::Command* RenderPass::generateCommandsImpl(CommandTypeFlags extraFlag
|
|||||||
bool const hasSkinningOrMorphing = hasSkinning || hasMorphing;
|
bool const hasSkinningOrMorphing = hasSkinning || hasMorphing;
|
||||||
|
|
||||||
// if we are already an SSR variant, the SRE bit is already set
|
// if we are already an SSR variant, the SRE bit is already set
|
||||||
static_assert(Variant::SPECIAL_SSR & Variant::SRE);
|
static_assert(Variant::SPECIAL_SSR_VARIANT & Variant::SRE);
|
||||||
Variant renderableVariant{ variant };
|
Variant renderableVariant{ variant };
|
||||||
|
|
||||||
// we can't have SSR and shadowing together by construction
|
// we can't have SSR and shadowing together by construction
|
||||||
|
|||||||
@@ -257,9 +257,9 @@ filament::DescriptorSetLayout const& FMaterial::getPerViewDescriptorSetLayout(
|
|||||||
}
|
}
|
||||||
// mDefinition.perViewDescriptorSetLayout{Vsm} is already resolved for MaterialDomain
|
// mDefinition.perViewDescriptorSetLayout{Vsm} is already resolved for MaterialDomain
|
||||||
if (useVsmDescriptorSetLayout) {
|
if (useVsmDescriptorSetLayout) {
|
||||||
return mDefinition.perViewDescriptorSetLayoutVsm;
|
return mDefinition.perViewDescriptorSetLayoutS2d;
|
||||||
}
|
}
|
||||||
return mDefinition.perViewDescriptorSetLayout;
|
return mDefinition.perViewDescriptorSetLayoutPcf;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FMaterial::compile(CompilerPriorityQueue const priority,
|
void FMaterial::compile(CompilerPriorityQueue const priority,
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ public:
|
|||||||
// This is mostly intended to be used for post-process materials; but it's also useful for
|
// This is mostly intended to be used for post-process materials; but it's also useful for
|
||||||
// Surface material that behave like post-process material (i.e. that don't really have variants or for
|
// Surface material that behave like post-process material (i.e. that don't really have variants or for
|
||||||
// which VSM is nonsensical, like for unlit materials)
|
// which VSM is nonsensical, like for unlit materials)
|
||||||
return mDefinition.perViewDescriptorSetLayout;
|
return mDefinition.perViewDescriptorSetLayoutPcf;
|
||||||
}
|
}
|
||||||
|
|
||||||
DescriptorSetLayout const& getPerViewDescriptorSetLayout(
|
DescriptorSetLayout const& getPerViewDescriptorSetLayout(
|
||||||
@@ -378,11 +378,11 @@ private:
|
|||||||
Variant variant = {}) const noexcept;
|
Variant variant = {}) const noexcept;
|
||||||
|
|
||||||
bool isSharedVariant(Variant const variant) const {
|
bool isSharedVariant(Variant const variant) const {
|
||||||
// HACK: The default material "should" have VSM | DEP, but then we'd have to compile it as a
|
// HACK: The default material "should" have MNT | DEP, but then we'd have to compile it as a
|
||||||
// lit material, which would increase binary size. Perhaps we could specially compile it
|
// lit material, which would increase binary size. Perhaps we could specially compile it
|
||||||
// with this variant, but with the shader program cache in active development, the days of
|
// with this variant, but with the shader program cache in active development, the days of
|
||||||
// the default material are numbered anyway.
|
// the default material are numbered anyway.
|
||||||
constexpr Variant::type_t vsmAndDep = Variant::VSM | Variant::DEP;
|
constexpr Variant::type_t vsmAndDep = Variant::MNT | Variant::DEP;
|
||||||
return mDefinition.materialDomain == MaterialDomain::SURFACE && !mIsDefaultMaterial &&
|
return mDefinition.materialDomain == MaterialDomain::SURFACE && !mIsDefaultMaterial &&
|
||||||
!mDefinition.hasCustomDepthShader && Variant::isValidDepthVariant(variant) &&
|
!mDefinition.hasCustomDepthShader && Variant::isValidDepthVariant(variant) &&
|
||||||
(variant.key & vsmAndDep) != vsmAndDep;
|
(variant.key & vsmAndDep) != vsmAndDep;
|
||||||
|
|||||||
@@ -969,10 +969,7 @@ void FRenderer::renderJob(DriverApi& driver, RootArenaScope& rootArenaScope, FVi
|
|||||||
variant.setDirectionalLighting(view.hasDirectionalLighting());
|
variant.setDirectionalLighting(view.hasDirectionalLighting());
|
||||||
variant.setDynamicLighting(view.hasDynamicLighting());
|
variant.setDynamicLighting(view.hasDynamicLighting());
|
||||||
variant.setFog(view.hasFog());
|
variant.setFog(view.hasFog());
|
||||||
// The VSM bit has a different meaning for STANDARD_VARIANT (as opposed to DEPTH_VARIANT),
|
variant.setShadowSampler2D(view.hasShadowing() && view.getShadowType() != ShadowType::PCF);
|
||||||
// In the STANDARD_VARIANT case, we are *using* the shadow-map, and the VSM only decides which
|
|
||||||
// type of sampler is used (samplerShadow or sampler2D).
|
|
||||||
variant.setVsm(view.hasShadowing() && view.getShadowType() != ShadowType::PCF);
|
|
||||||
variant.setStereo(view.hasStereo());
|
variant.setStereo(view.hasStereo());
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -981,10 +978,7 @@ void FRenderer::renderJob(DriverApi& driver, RootArenaScope& rootArenaScope, FVi
|
|||||||
|
|
||||||
if (view.needsShadowMap()) {
|
if (view.needsShadowMap()) {
|
||||||
Variant shadowVariant(Variant::DEPTH_VARIANT);
|
Variant shadowVariant(Variant::DEPTH_VARIANT);
|
||||||
// The VSM bit has a different meaning for DEPTH_VARIANT (as opposed to STANDARD_VARIANT),
|
shadowVariant.setDepthMoments(view.getShadowType() == ShadowType::VSM);
|
||||||
// In the DEPTH_VARIANT case, we are *generating* the shadow-map, and some computations
|
|
||||||
// are handled differently. In addition, the color buffer is used.
|
|
||||||
shadowVariant.setVsm(view.getShadowType() == ShadowType::VSM);
|
|
||||||
|
|
||||||
auto shadows = view.renderShadowMaps(engine, fg, cameraInfo, mShaderUserTime,
|
auto shadows = view.renderShadowMaps(engine, fg, cameraInfo, mShaderUserTime,
|
||||||
RenderPassBuilder{ commandArena }
|
RenderPassBuilder{ commandArena }
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ backend::DescriptorSetLayout const& getPerRenderableLayout() noexcept;
|
|||||||
backend::DescriptorSetLayout getPerViewDescriptorSetLayout(
|
backend::DescriptorSetLayout getPerViewDescriptorSetLayout(
|
||||||
MaterialDomain domain,
|
MaterialDomain domain,
|
||||||
bool isLit, bool isSSR, bool hasFog,
|
bool isLit, bool isSSR, bool hasFog,
|
||||||
bool isVSM) noexcept;
|
bool isShadowSampler2D) noexcept;
|
||||||
|
|
||||||
backend::DescriptorSetLayout getPerViewDescriptorSetLayoutWithVariant(
|
backend::DescriptorSetLayout getPerViewDescriptorSetLayoutWithVariant(
|
||||||
Variant variant,
|
Variant variant,
|
||||||
|
|||||||
@@ -48,20 +48,21 @@ struct Variant {
|
|||||||
// SRE: Shadow Receiver
|
// SRE: Shadow Receiver
|
||||||
// SKN: Skinning
|
// SKN: Skinning
|
||||||
// DEP: Depth only
|
// DEP: Depth only
|
||||||
// FOG: Fog
|
// FOG: Fog (standard)
|
||||||
// PCK: Picking (depth variant only)
|
// PCK: Picking (depth)
|
||||||
// VSM: Variance shadow maps (depth) / sampler type (standard)
|
// MNT: Output depth moments (depth)
|
||||||
|
// S2D: Sampler type for shadows (0: samplerShadowArray, 1: sampler2DArray) (standard)
|
||||||
// STE: Instanced stereo rendering
|
// STE: Instanced stereo rendering
|
||||||
//
|
//
|
||||||
// X: either 1 or 0
|
// X: either 1 or 0
|
||||||
// +-----+-----+-----+-----+-----+-----+-----+-----+
|
// +-----+-----+-----+-----+-----+-----+-----+-----+
|
||||||
// Variant | STE | VSM | FOG | DEP | SKN | SRE | DYN | DIR | 256
|
// Variant | STE | S2D | FOG | DEP | SKN | SRE | DYN | DIR | 256
|
||||||
// +-----+-----+-----+-----+-----+-----+-----+-----+
|
// +-----+-----+-----+-----+-----+-----+-----+-----+
|
||||||
// PCK
|
// MNT PCK
|
||||||
//
|
//
|
||||||
// Standard variants:
|
// Standard variants:
|
||||||
// +-----+-----+-----+-----+-----+-----+-----+-----+
|
// +-----+-----+-----+-----+-----+-----+-----+-----+
|
||||||
// | STE | VSM | FOG | 0 | SKN | SRE | DYN | DIR | 128 - 44 = 84
|
// | STE | S2D | FOG | 0 | SKN | SRE | DYN | DIR | 128 - 44 = 84
|
||||||
// +-----+-----+-----+-----+-----+-----+-----+-----+
|
// +-----+-----+-----+-----+-----+-----+-----+-----+
|
||||||
// Vertex shader X 0 0 0 X X X X
|
// Vertex shader X 0 0 0 X X X X
|
||||||
// Fragment shader 0 X X 0 0 X X X
|
// Fragment shader 0 X X 0 0 X X X
|
||||||
@@ -72,7 +73,7 @@ struct Variant {
|
|||||||
//
|
//
|
||||||
// Depth variants:
|
// Depth variants:
|
||||||
// +-----+-----+-----+-----+-----+-----+-----+-----+
|
// +-----+-----+-----+-----+-----+-----+-----+-----+
|
||||||
// | STE | VSM | PCK | 1 | SKN | 0 | 0 | 0 | 16 - 4 = 12
|
// | STE | MNT | PCK | 1 | SKN | 0 | 0 | 0 | 16 - 4 = 12
|
||||||
// +-----+-----+-----+-----+-----+-----+-----+-----+
|
// +-----+-----+-----+-----+-----+-----+-----+-----+
|
||||||
// Vertex depth X X 0 1 X 0 0 0
|
// Vertex depth X X 0 1 X 0 0 0
|
||||||
// Fragment depth 0 0 X 1 0 0 0 0
|
// Fragment depth 0 0 X 1 0 0 0 0
|
||||||
@@ -96,13 +97,15 @@ struct Variant {
|
|||||||
static constexpr type_t DEP = 0x10; // depth only variants
|
static constexpr type_t DEP = 0x10; // depth only variants
|
||||||
static constexpr type_t FOG = 0x20; // fog (standard)
|
static constexpr type_t FOG = 0x20; // fog (standard)
|
||||||
static constexpr type_t PCK = 0x20; // picking (depth)
|
static constexpr type_t PCK = 0x20; // picking (depth)
|
||||||
static constexpr type_t VSM = 0x40; // variance shadow maps / sampler type
|
static constexpr type_t S2D = 0x40; // sampler type
|
||||||
|
static constexpr type_t MNT = 0x40; // variance shadow maps
|
||||||
static constexpr type_t STE = 0x80; // instanced stereo
|
static constexpr type_t STE = 0x80; // instanced stereo
|
||||||
|
|
||||||
static constexpr type_t NO_VARIANT = 0u;
|
static constexpr type_t NO_VARIANT = 0u;
|
||||||
|
|
||||||
// special variants (variants that use the reserved space)
|
// special variants (variants that use the reserved space)
|
||||||
static constexpr type_t SPECIAL_SSR = VSM | SRE; // screen-space reflections variant
|
static constexpr type_t SPECIAL_SSR_VARIANT= S2D | SRE ;
|
||||||
|
static constexpr type_t SPECIAL_SSR_MASK = STE | S2D | DEP | SRE | DYN | DIR;
|
||||||
|
|
||||||
static constexpr type_t STANDARD_MASK = DEP;
|
static constexpr type_t STANDARD_MASK = DEP;
|
||||||
static constexpr type_t STANDARD_VARIANT = 0u;
|
static constexpr type_t STANDARD_VARIANT = 0u;
|
||||||
@@ -127,29 +130,30 @@ struct Variant {
|
|||||||
void setSkinning(bool v) noexcept { set(v, SKN); }
|
void setSkinning(bool v) noexcept { set(v, SKN); }
|
||||||
void setFog(bool v) noexcept { set(v, FOG); }
|
void setFog(bool v) noexcept { set(v, FOG); }
|
||||||
void setPicking(bool v) noexcept { set(v, PCK); }
|
void setPicking(bool v) noexcept { set(v, PCK); }
|
||||||
void setVsm(bool v) noexcept { set(v, VSM); }
|
void setShadowSampler2D(bool v) noexcept { set(v, S2D); }
|
||||||
|
void setDepthMoments(bool v) noexcept { set(v, MNT); }
|
||||||
void setStereo(bool v) noexcept { set(v, STE); }
|
void setStereo(bool v) noexcept { set(v, STE); }
|
||||||
|
|
||||||
static constexpr bool isValidDepthVariant(Variant variant) noexcept {
|
static constexpr bool isValidDepthVariant(Variant variant) noexcept {
|
||||||
// Can't have VSM and PICKING together with DEPTH variants
|
// Can't have VSM and PICKING together with DEPTH variants
|
||||||
constexpr type_t RESERVED_MASK = VSM | PCK | DEP | SRE | DYN | DIR;
|
constexpr type_t RESERVED_MASK = MNT | PCK | DEP | SRE | DYN | DIR;
|
||||||
constexpr type_t RESERVED_VALUE = VSM | PCK | DEP;
|
constexpr type_t RESERVED_VALUE = MNT | PCK | DEP;
|
||||||
return ((variant.key & DEPTH_MASK) == DEPTH_VARIANT) &&
|
return ((variant.key & DEPTH_MASK) == DEPTH_VARIANT) &&
|
||||||
((variant.key & RESERVED_MASK) != RESERVED_VALUE);
|
((variant.key & RESERVED_MASK) != RESERVED_VALUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr bool isValidStandardVariant(Variant variant) noexcept {
|
static constexpr bool isValidStandardVariant(Variant variant) noexcept {
|
||||||
// can't have shadow receiver if we don't have any lighting
|
// can't have shadow receiver if we don't have any lighting
|
||||||
constexpr type_t RESERVED0_MASK = VSM | FOG | SRE | DYN | DIR;
|
constexpr type_t RESERVED0_MASK = S2D | FOG | SRE | DYN | DIR;
|
||||||
constexpr type_t RESERVED0_VALUE = VSM | FOG | SRE;
|
constexpr type_t RESERVED0_VALUE = S2D | FOG | SRE;
|
||||||
|
|
||||||
// can't have shadow receiver if we don't have any lighting
|
// can't have shadow receiver if we don't have any lighting
|
||||||
constexpr type_t RESERVED1_MASK = VSM | SRE | DYN | DIR;
|
constexpr type_t RESERVED1_MASK = S2D | SRE | DYN | DIR;
|
||||||
constexpr type_t RESERVED1_VALUE = SRE;
|
constexpr type_t RESERVED1_VALUE = SRE;
|
||||||
|
|
||||||
// can't have VSM without shadow receiver
|
// can't have VSM without shadow receiver
|
||||||
constexpr type_t RESERVED2_MASK = VSM | SRE;
|
constexpr type_t RESERVED2_MASK = S2D | SRE;
|
||||||
constexpr type_t RESERVED2_VALUE = VSM;
|
constexpr type_t RESERVED2_VALUE = S2D;
|
||||||
|
|
||||||
return ((variant.key & STANDARD_MASK) == STANDARD_VARIANT) &&
|
return ((variant.key & STANDARD_MASK) == STANDARD_VARIANT) &&
|
||||||
((variant.key & RESERVED0_MASK) != RESERVED0_VALUE) &&
|
((variant.key & RESERVED0_MASK) != RESERVED0_VALUE) &&
|
||||||
@@ -174,11 +178,15 @@ struct Variant {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static constexpr bool isSSRVariant(Variant variant) noexcept {
|
static constexpr bool isSSRVariant(Variant variant) noexcept {
|
||||||
return (variant.key & (STE | VSM | DEP | SRE | DYN | DIR)) == (VSM | SRE);
|
return (variant.key & SPECIAL_SSR_MASK) == SPECIAL_SSR_VARIANT;
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr bool isVSMVariant(Variant variant) noexcept {
|
static constexpr bool isShadowSampler2DVariant(Variant variant) noexcept {
|
||||||
return !isSSRVariant(variant) && ((variant.key & VSM) == VSM);
|
return !isSSRVariant(variant) && ((variant.key & (S2D | DEP)) == S2D);
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr bool isDepthMomentsVariant(Variant variant) noexcept {
|
||||||
|
return !isSSRVariant(variant) && ((variant.key & (MNT | DEP)) == (MNT | DEP));
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr bool isShadowReceiverVariant(Variant variant) noexcept {
|
static constexpr bool isShadowReceiverVariant(Variant variant) noexcept {
|
||||||
@@ -202,13 +210,13 @@ struct Variant {
|
|||||||
// vertex shader.
|
// vertex shader.
|
||||||
if ((variant.key & STANDARD_MASK) == STANDARD_VARIANT) {
|
if ((variant.key & STANDARD_MASK) == STANDARD_VARIANT) {
|
||||||
if (isSSRVariant(variant)) {
|
if (isSSRVariant(variant)) {
|
||||||
variant.key &= ~(VSM | SRE);
|
variant.key &= ~SPECIAL_SSR_VARIANT;
|
||||||
}
|
}
|
||||||
return variant & (STE | SKN | SRE | DYN | DIR);
|
return variant & (STE | SKN | SRE | DYN | DIR);
|
||||||
}
|
}
|
||||||
if ((variant.key & DEPTH_MASK) == DEPTH_VARIANT) {
|
if ((variant.key & DEPTH_MASK) == DEPTH_VARIANT) {
|
||||||
// Only VSM, skinning, and stereo affect the vertex shader's DEPTH variant
|
// Only MNT, skinning, and stereo affect the vertex shader's DEPTH variant
|
||||||
return variant & (STE | VSM | SKN | DEP);
|
return variant & (STE | MNT | SKN | DEP);
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
@@ -217,11 +225,11 @@ struct Variant {
|
|||||||
// filter out fragment variants that are not needed. For e.g. skinning doesn't
|
// filter out fragment variants that are not needed. For e.g. skinning doesn't
|
||||||
// affect the fragment shader.
|
// affect the fragment shader.
|
||||||
if ((variant.key & STANDARD_MASK) == STANDARD_VARIANT) {
|
if ((variant.key & STANDARD_MASK) == STANDARD_VARIANT) {
|
||||||
return variant & (VSM | FOG | SRE | DYN | DIR);
|
return variant & (S2D | FOG | SRE | DYN | DIR);
|
||||||
}
|
}
|
||||||
if ((variant.key & DEPTH_MASK) == DEPTH_VARIANT) {
|
if ((variant.key & DEPTH_MASK) == DEPTH_VARIANT) {
|
||||||
// Only VSM & PICKING affects the fragment shader's DEPTH variant
|
// Only VSM & PICKING affects the fragment shader's DEPTH variant
|
||||||
return variant & (VSM | PCK | DEP);
|
return variant & (MNT | PCK | DEP);
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
@@ -230,8 +238,8 @@ struct Variant {
|
|||||||
// special case for depth variant
|
// special case for depth variant
|
||||||
if (isValidDepthVariant(variant)) {
|
if (isValidDepthVariant(variant)) {
|
||||||
if (!isLit) {
|
if (!isLit) {
|
||||||
// if we're unlit, we never need the VSM variant
|
// if we're unlit, we never need the MNT variant
|
||||||
return variant & ~VSM;
|
return variant & ~MNT;
|
||||||
}
|
}
|
||||||
return variant;
|
return variant;
|
||||||
}
|
}
|
||||||
@@ -242,9 +250,9 @@ struct Variant {
|
|||||||
// when the shading mode is unlit, remove all the lighting variants
|
// when the shading mode is unlit, remove all the lighting variants
|
||||||
return variant & UNLIT_MASK;
|
return variant & UNLIT_MASK;
|
||||||
}
|
}
|
||||||
// if shadow receiver is disabled, turn off VSM
|
// if shadow receiver is disabled, we pick the shadow sampler
|
||||||
if (!(variant.key & SRE)) {
|
if (!(variant.key & SRE)) {
|
||||||
return variant & ~VSM;
|
return variant & ~S2D;
|
||||||
}
|
}
|
||||||
return variant;
|
return variant;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -216,7 +216,7 @@ utils::CString getDescriptorName(DescriptorSetBindingPoints const set,
|
|||||||
DescriptorSetLayout getPerViewDescriptorSetLayout(
|
DescriptorSetLayout getPerViewDescriptorSetLayout(
|
||||||
MaterialDomain const domain,
|
MaterialDomain const domain,
|
||||||
bool const isLit, bool const isSSR, bool const hasFog,
|
bool const isLit, bool const isSSR, bool const hasFog,
|
||||||
bool const isVSM) noexcept {
|
bool const isShadowSampler2D) noexcept {
|
||||||
|
|
||||||
switch (domain) {
|
switch (domain) {
|
||||||
case MaterialDomain::SURFACE: {
|
case MaterialDomain::SURFACE: {
|
||||||
@@ -255,7 +255,7 @@ DescriptorSetLayout getPerViewDescriptorSetLayout(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// change the SHADOW_MAP descriptor type for VSM
|
// change the SHADOW_MAP descriptor type for VSM
|
||||||
if (isVSM) {
|
if (isShadowSampler2D) {
|
||||||
auto const pos = std::find_if(layout.descriptors.begin(), layout.descriptors.end(),
|
auto const pos = std::find_if(layout.descriptors.begin(), layout.descriptors.end(),
|
||||||
[](auto const& v) {
|
[](auto const& v) {
|
||||||
return v.binding == PerViewBindingPoints::SHADOW_MAP;
|
return v.binding == PerViewBindingPoints::SHADOW_MAP;
|
||||||
@@ -285,8 +285,7 @@ DescriptorSetLayout getPerViewDescriptorSetLayoutWithVariant(
|
|||||||
return ssrVariantDescriptorSetLayout;
|
return ssrVariantDescriptorSetLayout;
|
||||||
}
|
}
|
||||||
// We need to filter out all the descriptors not included in the "resolved" layout below
|
// We need to filter out all the descriptors not included in the "resolved" layout below
|
||||||
return getPerViewDescriptorSetLayout(domain, isLit, isSSR, hasFog,
|
return getPerViewDescriptorSetLayout(domain, isLit, isSSR, hasFog, Variant::isShadowSampler2DVariant(variant));
|
||||||
Variant::isVSMVariant(variant));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DescriptorType getDescriptorType(SamplerType const type, SamplerFormat const format) {
|
DescriptorType getDescriptorType(SamplerType const type, SamplerFormat const format) {
|
||||||
|
|||||||
@@ -32,41 +32,46 @@ namespace filament {
|
|||||||
Variant Variant::filterUserVariant(
|
Variant Variant::filterUserVariant(
|
||||||
Variant variant, UserVariantFilterMask filterMask) noexcept {
|
Variant variant, UserVariantFilterMask filterMask) noexcept {
|
||||||
// these are easy to filter by just removing the corresponding bit
|
// these are easy to filter by just removing the corresponding bit
|
||||||
if (filterMask & (uint32_t)UserVariantFilterBit::DIRECTIONAL_LIGHTING) {
|
if (filterMask & uint32_t(UserVariantFilterBit::DIRECTIONAL_LIGHTING)) {
|
||||||
variant.key &= ~DIR;
|
variant.key &= ~DIR;
|
||||||
}
|
}
|
||||||
if (filterMask & (uint32_t)UserVariantFilterBit::DYNAMIC_LIGHTING) {
|
|
||||||
|
if (filterMask & uint32_t(UserVariantFilterBit::DYNAMIC_LIGHTING)) {
|
||||||
variant.key &= ~DYN;
|
variant.key &= ~DYN;
|
||||||
}
|
}
|
||||||
if (filterMask & (uint32_t)UserVariantFilterBit::SKINNING) {
|
|
||||||
|
if (filterMask & uint32_t(UserVariantFilterBit::SKINNING)) {
|
||||||
variant.key &= ~SKN;
|
variant.key &= ~SKN;
|
||||||
}
|
}
|
||||||
if (filterMask & (uint32_t)UserVariantFilterBit::STE) {
|
|
||||||
|
if (filterMask & uint32_t(UserVariantFilterBit::STE)) {
|
||||||
variant.key &= ~(filterMask & STE);
|
variant.key &= ~(filterMask & STE);
|
||||||
}
|
}
|
||||||
if (!isValidDepthVariant(variant)) {
|
|
||||||
// we can't remove FOG from depth variants, this would, in fact, remove picking
|
if (isValidDepthVariant(variant)) {
|
||||||
if (filterMask & (uint32_t)UserVariantFilterBit::FOG) {
|
// depth variants can have their MNT bit filtered
|
||||||
variant.key &= ~FOG;
|
if (filterMask & uint32_t(UserVariantFilterBit::VSM)) {
|
||||||
|
variant.key &= ~MNT;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// depth variants can have their VSM bit filtered
|
// we can't remove FOG from depth variants, this would, in fact, remove picking
|
||||||
if (filterMask & (uint32_t)UserVariantFilterBit::VSM) {
|
if (filterMask & uint32_t(UserVariantFilterBit::FOG)) {
|
||||||
variant.key &= ~VSM;
|
variant.key &= ~FOG;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isSSRVariant(variant)) {
|
if (!isSSRVariant(variant)) {
|
||||||
// SSR variant needs to be handled separately
|
// SSR variant needs to be handled separately
|
||||||
if (filterMask & (uint32_t)UserVariantFilterBit::SHADOW_RECEIVER) {
|
if (filterMask & uint32_t(UserVariantFilterBit::SHADOW_RECEIVER)) {
|
||||||
variant.key &= ~SRE;
|
variant.key &= ~SRE;
|
||||||
}
|
}
|
||||||
if (filterMask & (uint32_t)UserVariantFilterBit::VSM) {
|
if (filterMask & uint32_t(UserVariantFilterBit::VSM)) {
|
||||||
variant.key &= ~VSM;
|
variant.key &= ~S2D;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// see if we need to filter out the SSR variants
|
// see if we need to filter out the SSR variants
|
||||||
if (filterMask & (uint32_t)UserVariantFilterBit::SSR) {
|
if (filterMask & uint32_t(UserVariantFilterBit::SSR)) {
|
||||||
variant.key &= ~SPECIAL_SSR;
|
variant.key &= ~SPECIAL_SSR_VARIANT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return variant;
|
return variant;
|
||||||
|
|||||||
@@ -60,7 +60,8 @@ void ShaderGenerator::generateSurfaceMaterialVariantDefines(io::sstream& out,
|
|||||||
CodeGenerator::generateDefine(out, "VARIANT_HAS_SHADOWING",
|
CodeGenerator::generateDefine(out, "VARIANT_HAS_SHADOWING",
|
||||||
litVariants && filament::Variant::isShadowReceiverVariant(variant));
|
litVariants && filament::Variant::isShadowReceiverVariant(variant));
|
||||||
CodeGenerator::generateDefine(out, "VARIANT_HAS_VSM",
|
CodeGenerator::generateDefine(out, "VARIANT_HAS_VSM",
|
||||||
filament::Variant::isVSMVariant(variant));
|
filament::Variant::isShadowSampler2DVariant(variant) ||
|
||||||
|
filament::Variant::isDepthMomentsVariant(variant));
|
||||||
CodeGenerator::generateDefine(out, "VARIANT_HAS_STEREO",
|
CodeGenerator::generateDefine(out, "VARIANT_HAS_STEREO",
|
||||||
hasStereo(variant, featureLevel));
|
hasStereo(variant, featureLevel));
|
||||||
CodeGenerator::generateDefine(out, "VARIANT_DEPTH",
|
CodeGenerator::generateDefine(out, "VARIANT_DEPTH",
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ SamplerInterfaceBlock const& SibGenerator::getPerViewSib(Variant variant) noexce
|
|||||||
// reason we name them "unused*" to ensure we're not using them by mistake (type/format don't
|
// reason we name them "unused*" to ensure we're not using them by mistake (type/format don't
|
||||||
// matter).
|
// matter).
|
||||||
|
|
||||||
static SamplerInterfaceBlock const sibPcf{ SamplerInterfaceBlock::Builder()
|
static SamplerInterfaceBlock const sibShadowSamplerPcf{ SamplerInterfaceBlock::Builder()
|
||||||
.name("sampler0")
|
.name("sampler0")
|
||||||
.stageFlags(backend::ShaderStageFlags::FRAGMENT)
|
.stageFlags(backend::ShaderStageFlags::FRAGMENT)
|
||||||
.add( {{ "shadowMap", +PerViewBindingPoints::SHADOW_MAP, Type::SAMPLER_2D_ARRAY, Format::SHADOW, Precision::MEDIUM, FILTERABLE, !MULTISAMPLE, ALL_STAGES },
|
.add( {{ "shadowMap", +PerViewBindingPoints::SHADOW_MAP, Type::SAMPLER_2D_ARRAY, Format::SHADOW, Precision::MEDIUM, FILTERABLE, !MULTISAMPLE, ALL_STAGES },
|
||||||
@@ -62,7 +62,7 @@ SamplerInterfaceBlock const& SibGenerator::getPerViewSib(Variant variant) noexce
|
|||||||
)
|
)
|
||||||
.build() };
|
.build() };
|
||||||
|
|
||||||
static SamplerInterfaceBlock const sibVsm{ SamplerInterfaceBlock::Builder()
|
static SamplerInterfaceBlock const sibShadowSampler2D{ SamplerInterfaceBlock::Builder()
|
||||||
.name("sampler0")
|
.name("sampler0")
|
||||||
.stageFlags(backend::ShaderStageFlags::FRAGMENT)
|
.stageFlags(backend::ShaderStageFlags::FRAGMENT)
|
||||||
.add( {{ "shadowMap", +PerViewBindingPoints::SHADOW_MAP, Type::SAMPLER_2D_ARRAY, Format::FLOAT, Precision::HIGH, FILTERABLE, !MULTISAMPLE, ALL_STAGES },
|
.add( {{ "shadowMap", +PerViewBindingPoints::SHADOW_MAP, Type::SAMPLER_2D_ARRAY, Format::FLOAT, Precision::HIGH, FILTERABLE, !MULTISAMPLE, ALL_STAGES },
|
||||||
@@ -85,10 +85,10 @@ SamplerInterfaceBlock const& SibGenerator::getPerViewSib(Variant variant) noexce
|
|||||||
|
|
||||||
if (Variant::isSSRVariant(variant)) {
|
if (Variant::isSSRVariant(variant)) {
|
||||||
return sibSsr;
|
return sibSsr;
|
||||||
} else if (Variant::isVSMVariant(variant)) {
|
} else if (Variant::isShadowSampler2DVariant(variant)) {
|
||||||
return sibVsm;
|
return sibShadowSampler2D;
|
||||||
} else {
|
} else {
|
||||||
return sibPcf;
|
return sibShadowSamplerPcf;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -48,10 +48,11 @@ std::string formatVariantString(Variant variant, MaterialDomain domain) noexcept
|
|||||||
if (variant.key & Variant::DEP) variantString += "DEP|";
|
if (variant.key & Variant::DEP) variantString += "DEP|";
|
||||||
if (variant.key & Variant::DEP) {
|
if (variant.key & Variant::DEP) {
|
||||||
if (variant.key & Variant::PCK) variantString += "PCK|";
|
if (variant.key & Variant::PCK) variantString += "PCK|";
|
||||||
|
if (variant.key & Variant::MNT) variantString += "MNT|";
|
||||||
} else {
|
} else {
|
||||||
if (variant.key & Variant::FOG) variantString += "FOG|";
|
if (variant.key & Variant::FOG) variantString += "FOG|";
|
||||||
|
if (variant.key & Variant::S2D) variantString += "S2D|";
|
||||||
}
|
}
|
||||||
if (variant.key & Variant::VSM) variantString += "VSM|";
|
|
||||||
if (variant.key & Variant::STE) variantString += "STE|";
|
if (variant.key & Variant::STE) variantString += "STE|";
|
||||||
variantString = variantString.substr(0, variantString.length() - 1);
|
variantString = variantString.substr(0, variantString.length() - 1);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ into **branch** of `filament-assets`. This branch is paired with a PR or commit
|
|||||||
|
|
||||||
As an example, imagine I am working on a PR, and I've uploaded my change, which is in a
|
As an example, imagine I am working on a PR, and I've uploaded my change, which is in a
|
||||||
branch called `my-pr-branch`, to `filament`. This PR requires updating the golden. We would do
|
branch called `my-pr-branch`, to `filament`. This PR requires updating the golden. We would do
|
||||||
it in the following fashion
|
it in the following fashion on a macOS machine:
|
||||||
|
|
||||||
### Using a script to update the golden repo
|
### Using a script to update the golden repo
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user