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:
committed by
Mathias Agopian
parent
d114d547be
commit
001dcefd8a
@@ -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
@@ -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
@@ -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
@@ -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) { }
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user