simplify how we select a material Variant

Instead of building the Variant based on flags in RenderPass, we just
pass the Variant itself to RenderPass. The caller has more knowledge
of what it wants to do.
This commit is contained in:
Mathias Agopian
2022-01-27 15:48:24 -08:00
committed by Mathias Agopian
parent d114d547be
commit 001dcefd8a
5 changed files with 49 additions and 50 deletions
+4
View File
@@ -382,8 +382,12 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::structure(FrameGraph& fg,
},
[=, renderPass = pass](FrameGraphResources const& resources,
auto const& data, DriverApi& driver) mutable {
Variant structureVariant(Variant::DEPTH_VARIANT);
structureVariant.setPicking(config.picking);
auto out = resources.getRenderPassInfo();
renderPass.setRenderFlags(structureRenderFlags);
renderPass.setVariant(structureVariant);
renderPass.appendCommands(RenderPass::CommandTypeFlags::SSAO);
renderPass.sortCommands();
renderPass.execute(resources.getPassName(), out.target, out.params);
+15 -22
View File
@@ -94,6 +94,7 @@ void RenderPass::appendCommands(CommandTypeFlags const commandTypeFlags) noexcep
FEngine& engine = mEngine;
JobSystem& js = engine.getJobSystem();
const RenderFlags renderFlags = mFlags;
const Variant variant = mVariant;
const FScene::VisibleMaskType visibilityMask = mVisibilityMask;
CameraInfo const& camera = mCamera;
@@ -113,11 +114,11 @@ void RenderPass::appendCommands(CommandTypeFlags const commandTypeFlags) noexcep
// we extract camera position/forward outside of the loop, because these are not cheap.
const float3 cameraPosition(camera.getPosition());
const float3 cameraForwardVector(camera.getForwardVector());
auto work = [commandTypeFlags, curr, &soa, renderFlags, visibilityMask, cameraPosition,
auto work = [commandTypeFlags, curr, &soa, variant, renderFlags, visibilityMask, cameraPosition,
cameraForwardVector]
(uint32_t startIndex, uint32_t indexCount) {
RenderPass::generateCommands(commandTypeFlags, curr,
soa, { startIndex, startIndex + indexCount }, renderFlags, visibilityMask,
soa, { startIndex, startIndex + indexCount }, variant, renderFlags, visibilityMask,
cameraPosition, cameraForwardVector);
};
@@ -211,8 +212,10 @@ void RenderPass::setupColorCommand(Command& cmdDraw,
/* static */
UTILS_NOINLINE
void RenderPass::generateCommands(uint32_t commandTypeFlags, Command* const commands,
FScene::RenderableSoa const& soa, Range<uint32_t> range, RenderFlags renderFlags,
FScene::VisibleMaskType visibilityMask, float3 cameraPosition, float3 cameraForward) noexcept {
FScene::RenderableSoa const& soa, Range<uint32_t> range,
Variant variant, RenderFlags renderFlags,
FScene::VisibleMaskType visibilityMask,
float3 cameraPosition, float3 cameraForward) noexcept {
// generateCommands() writes both the draw and depth commands simultaneously such that
// we go throw the list of renderables just once.
@@ -239,11 +242,11 @@ void RenderPass::generateCommands(uint32_t commandTypeFlags, Command* const comm
switch (commandTypeFlags & (CommandTypeFlags::COLOR | CommandTypeFlags::DEPTH)) {
case CommandTypeFlags::COLOR:
generateCommandsImpl<CommandTypeFlags::COLOR>(commandTypeFlags, curr,
soa, range, renderFlags, visibilityMask, cameraPosition, cameraForward);
soa, range, variant, renderFlags, visibilityMask, cameraPosition, cameraForward);
break;
case CommandTypeFlags::DEPTH:
generateCommandsImpl<CommandTypeFlags::DEPTH>(commandTypeFlags, curr,
soa, range, renderFlags, visibilityMask, cameraPosition, cameraForward);
soa, range, variant, renderFlags, visibilityMask, cameraPosition, cameraForward);
break;
default:
// we should never end-up here
@@ -257,7 +260,7 @@ UTILS_NOINLINE
void RenderPass::generateCommandsImpl(uint32_t extraFlags,
Command* UTILS_RESTRICT curr,
FScene::RenderableSoa const& UTILS_RESTRICT soa, Range<uint32_t> range,
RenderFlags renderFlags, FScene::VisibleMaskType visibilityMask,
Variant variant, RenderFlags renderFlags, FScene::VisibleMaskType visibilityMask,
float3 cameraPosition, float3 cameraForward) noexcept {
// generateCommands() writes both the draw and depth commands simultaneously such that
@@ -283,23 +286,13 @@ void RenderPass::generateCommandsImpl(uint32_t extraFlags,
const bool hasShadowing = renderFlags & HAS_SHADOWING;
const bool viewInverseFrontFaces = renderFlags & HAS_INVERSE_FRONT_FACES;
Variant materialVariant;
materialVariant.setDirectionalLighting(renderFlags & HAS_DIRECTIONAL_LIGHT);
materialVariant.setDynamicLighting(renderFlags & HAS_DYNAMIC_LIGHTING);
materialVariant.setFog(renderFlags & HAS_FOG);
// DPCF and PCSS uses the same color pass shader as VSM (but not for depth)
materialVariant.setVsm(((renderFlags & HAS_VSM) || (renderFlags & HAS_DPCF_OR_PCSS)) && hasShadowing);
materialVariant.setShadowReceiver(false); // this is set per Renderable
Command cmdColor;
Command cmdDepth;
if constexpr (isDepthPass) {
cmdDepth.primitive.materialVariant = Variant{ Variant::DEPTH_VARIANT };
cmdDepth.primitive.materialVariant.setPicking(renderFlags & HAS_PICKING);
cmdDepth.primitive.materialVariant.setVsm(renderFlags & HAS_VSM);
cmdDepth.primitive.materialVariant = variant;
cmdDepth.primitive.rasterState = {};
cmdDepth.primitive.rasterState.colorWrite = renderFlags & (HAS_VSM | HAS_PICKING);
cmdDepth.primitive.rasterState.colorWrite = variant.hasPicking() || variant.hasVsm();
cmdDepth.primitive.rasterState.depthWrite = true;
cmdDepth.primitive.rasterState.depthFunc = RasterState::DepthFunc::GE;
cmdDepth.primitive.rasterState.alphaToCoverage = false;
@@ -355,8 +348,8 @@ void RenderPass::generateCommandsImpl(uint32_t extraFlags,
cmdColor.key = makeField(soaVisibility[i].priority, PRIORITY_MASK, PRIORITY_SHIFT);
cmdColor.primitive.index = (uint16_t)i;
materialVariant.setShadowReceiver(soaVisibility[i].receiveShadows & hasShadowing);
materialVariant.setSkinning(soaVisibility[i].skinning || soaVisibility[i].morphing);
variant.setShadowReceiver(soaVisibility[i].receiveShadows & hasShadowing);
variant.setSkinning(soaVisibility[i].skinning || soaVisibility[i].morphing);
if constexpr (isDepthPass) {
cmdDepth.key = uint64_t(Pass::DEPTH);
@@ -384,7 +377,7 @@ void RenderPass::generateCommandsImpl(uint32_t extraFlags,
FMorphTargetBuffer const* const morphTargetBuffer = primitive.getMorphTargetBuffer();
if constexpr (isColorPass) {
cmdColor.primitive.primitiveHandle = primitive.getHwHandle();
cmdColor.primitive.materialVariant = materialVariant;
cmdColor.primitive.materialVariant = variant;
RenderPass::setupColorCommand(cmdColor, mi, inverseFrontFaces);
cmdColor.primitive.morphWeightBuffer = morphing.handle;
+12 -10
View File
@@ -238,13 +238,7 @@ public:
using RenderFlags = uint8_t;
static constexpr RenderFlags HAS_SHADOWING = 0x01;
static constexpr RenderFlags HAS_DIRECTIONAL_LIGHT = 0x02;
static constexpr RenderFlags HAS_DYNAMIC_LIGHTING = 0x04;
static constexpr RenderFlags HAS_INVERSE_FRONT_FACES = 0x08;
static constexpr RenderFlags HAS_FOG = 0x10;
static constexpr RenderFlags HAS_VSM = 0x20;
static constexpr RenderFlags HAS_PICKING = 0x40;
static constexpr RenderFlags HAS_DPCF_OR_PCSS = 0x80;
static constexpr RenderFlags HAS_INVERSE_FRONT_FACES = 0x02;
// Arena used for commands
using Arena = utils::Arena<
@@ -279,6 +273,9 @@ public:
// flags controlling how commands are generated
void setRenderFlags(RenderFlags flags) noexcept { mFlags = flags; }
// variant to use
void setVariant(Variant variant) noexcept { mVariant = variant; }
// Sets the visibility mask, which is AND-ed against each Renderable's VISIBLE_MASK to determine
// if the renderable is visible for this pass.
// Defaults to all 1's, which means all renderables in this render pass will be rendered.
@@ -369,13 +366,15 @@ private:
"Size of Commands jobs must be multiple of a cache-line size");
static inline void generateCommands(uint32_t commandTypeFlags, Command* commands,
FScene::RenderableSoa const& soa, utils::Range<uint32_t> range, RenderFlags renderFlags,
FScene::VisibleMaskType visibilityMask, math::float3 cameraPosition, math::float3 cameraForward) noexcept;
FScene::RenderableSoa const& soa, utils::Range<uint32_t> range,
Variant variant, RenderFlags renderFlags,
FScene::VisibleMaskType visibilityMask,
math::float3 cameraPosition, math::float3 cameraForward) noexcept;
template<uint32_t commandTypeFlags>
static inline void generateCommandsImpl(uint32_t, Command* commands,
FScene::RenderableSoa const& soa, utils::Range<uint32_t> range,
RenderFlags renderFlags, FScene::VisibleMaskType visibilityMask,
Variant variant, RenderFlags renderFlags, FScene::VisibleMaskType visibilityMask,
math::float3 cameraPosition, math::float3 cameraForward) noexcept;
static void setupColorCommand(Command& cmdDraw,
@@ -415,6 +414,9 @@ private:
// info about the scene features (e.g.: has shadows, lighting, etc...)
RenderFlags mFlags{};
// Variant to use
Variant mVariant{};
// Additional visibility mask
FScene::VisibleMaskType mVisibilityMask = std::numeric_limits<FScene::VisibleMaskType>::max();
+16 -18
View File
@@ -285,23 +285,16 @@ void FRenderer::renderJob(ArenaScope& arena, FView& view) {
RenderPass::Arena commandArena("Command Arena", { arenaBegin, arenaEnd });
RenderPass pass(engine, commandArena);
RenderPass::RenderFlags baseRenderFlags = 0;
if (view.hasShadowing()) baseRenderFlags |= RenderPass::HAS_SHADOWING;
if (view.hasDirectionalLight()) baseRenderFlags |= RenderPass::HAS_DIRECTIONAL_LIGHT;
if (view.hasDynamicLighting()) baseRenderFlags |= RenderPass::HAS_DYNAMIC_LIGHTING;
if (view.hasFog()) baseRenderFlags |= RenderPass::HAS_FOG;
if (view.isFrontFaceWindingInverted()) baseRenderFlags |= RenderPass::HAS_INVERSE_FRONT_FACES;
RenderPass::RenderFlags colorRenderFlags = baseRenderFlags;
switch (view.getShadowType()) {
case ShadowType::PCF: break;
case ShadowType::VSM: colorRenderFlags |= RenderPass::HAS_VSM; break;
case ShadowType::DPCF: colorRenderFlags |= RenderPass::HAS_DPCF_OR_PCSS; break;
case ShadowType::PCSS: colorRenderFlags |= RenderPass::HAS_DPCF_OR_PCSS; break;
}
RenderPass::RenderFlags renderFlags = 0;
if (view.hasShadowing()) renderFlags |= RenderPass::HAS_SHADOWING;
if (view.isFrontFaceWindingInverted()) renderFlags |= RenderPass::HAS_INVERSE_FRONT_FACES;
RenderPass::RenderFlags structureRenderFlags = baseRenderFlags;
if (view.hasPicking()) structureRenderFlags |= RenderPass::HAS_PICKING;
Variant variant;
variant.setDirectionalLighting(view.hasDirectionalLight());
variant.setDynamicLighting(view.hasDynamicLighting());
variant.setFog(view.hasFog());
variant.setVsm(view.hasShadowing() && view.getShadowType() != ShadowType::PCF);
/*
* Frame graph
@@ -314,8 +307,12 @@ void FRenderer::renderJob(ArenaScope& arena, FView& view) {
*/
if (view.needsShadowMap()) {
Variant shadowVariant(Variant::DEPTH_VARIANT);
shadowVariant.setVsm(view.getShadowType() == ShadowType::VSM);
RenderPass shadowPass(pass);
shadowPass.setRenderFlags(colorRenderFlags);
shadowPass.setRenderFlags(renderFlags);
shadowPass.setVariant(shadowVariant);
view.renderShadowMaps(fg, engine, driver, shadowPass);
}
@@ -436,7 +433,7 @@ void FRenderer::renderJob(ArenaScope& arena, FView& view) {
// This is normally used by SSAO and contact-shadows
// TODO: the scaling should depends on all passes that need the structure pass
ppm.structure(fg, pass, structureRenderFlags, svp.width, svp.height, {
ppm.structure(fg, pass, renderFlags, svp.width, svp.height, {
.scale = aoOptions.resolution,
.picking = view.hasPicking()
});
@@ -503,7 +500,8 @@ void FRenderer::renderJob(ArenaScope& arena, FView& view) {
// This one doesn't need to be a FrameGraph pass because it always happens by construction
// (i.e. it won't be culled, unless everything is culled), so no need to complexify things.
pass.setRenderFlags(colorRenderFlags);
pass.setRenderFlags(renderFlags);
pass.setVariant(variant);
pass.appendCommands(RenderPass::COLOR);
pass.sortCommands();
@@ -34,6 +34,8 @@ namespace filament {
using type_t = uint8_t;
Variant() noexcept = default;
Variant(Variant const& rhs) noexcept = default;
Variant& operator=(Variant const& rhs) noexcept = default;
constexpr explicit Variant(type_t key) noexcept : key(key) { }