use a separate UBO for the postfx user passes
some of the postfx passes (picking, ssao, structure) are user passes because they call user materials; these now use their own ubo, which should prevent us from having to update a UBO mid frame.
This commit is contained in:
committed by
Mathias Agopian
parent
1b2620cdf3
commit
5850a7eee4
@@ -329,6 +329,7 @@ void PostProcessManager::init() noexcept {
|
||||
|
||||
mSsrPassDescriptorSet.init(engine);
|
||||
mPostProcessDescriptorSet.init(engine);
|
||||
mStructureDescriptorSet.init(engine);
|
||||
|
||||
mWorkaroundSplitEasu =
|
||||
driver.isWorkaroundNeeded(Workaround::SPLIT_EASU);
|
||||
@@ -405,6 +406,7 @@ void PostProcessManager::terminate(DriverApi& driver) noexcept {
|
||||
|
||||
mPostProcessDescriptorSet.terminate(engine.getDescriptorSetLayoutFactory(), driver);
|
||||
mSsrPassDescriptorSet.terminate(driver);
|
||||
mStructureDescriptorSet.terminate(driver);
|
||||
}
|
||||
|
||||
Handle<HwTexture> PostProcessManager::getOneTexture() const {
|
||||
@@ -546,7 +548,8 @@ PostProcessManager::StructurePassOutput PostProcessManager::structure(FrameGraph
|
||||
Variant structureVariant(Variant::DEPTH_VARIANT);
|
||||
structureVariant.setPicking(config.picking);
|
||||
|
||||
bindPostProcessDescriptorSet(driver);
|
||||
// bind the per-view descriptorSet that is used for the structure pass
|
||||
getStructureDescriptorSet().bind(driver);
|
||||
|
||||
passBuilder.renderFlags(structureRenderFlags);
|
||||
passBuilder.variant(structureVariant);
|
||||
@@ -609,6 +612,63 @@ PostProcessManager::StructurePassOutput PostProcessManager::structure(FrameGraph
|
||||
return { depth, structurePass->picking };
|
||||
}
|
||||
|
||||
FrameGraphId<FrameGraphTexture> PostProcessManager::transparentPicking(FrameGraph& fg,
|
||||
RenderPassBuilder const& passBuilder, uint8_t const structureRenderFlags,
|
||||
uint32_t width, uint32_t height, float const scale) noexcept {
|
||||
|
||||
struct PickingRenderPassData {
|
||||
FrameGraphId<FrameGraphTexture> depth;
|
||||
FrameGraphId<FrameGraphTexture> picking;
|
||||
};
|
||||
auto const& pickingRenderPass = fg.addPass<PickingRenderPassData>("Picking Render Pass",
|
||||
[&](FrameGraph::Builder& builder, auto& data) {
|
||||
bool const isFL0 = mEngine.getDriverApi().getFeatureLevel() ==
|
||||
FeatureLevel::FEATURE_LEVEL_0;
|
||||
|
||||
// TODO: Specify the precision for picking pass
|
||||
width = std::max(32u, uint32_t(std::ceil(float(width) * scale)));
|
||||
height = std::max(32u, uint32_t(std::ceil(float(height) * scale)));
|
||||
data.depth = builder.createTexture("Depth Buffer", {
|
||||
.width = width, .height = height,
|
||||
.format = isFL0 ? TextureFormat::DEPTH24 : TextureFormat::DEPTH32F });
|
||||
|
||||
data.depth = builder.write(data.depth,
|
||||
FrameGraphTexture::Usage::DEPTH_ATTACHMENT);
|
||||
|
||||
data.picking = builder.createTexture("Picking Buffer", {
|
||||
.width = width, .height = height,
|
||||
.format = isFL0 ? TextureFormat::RGBA8 : TextureFormat::RG32F });
|
||||
|
||||
data.picking = builder.write(data.picking,
|
||||
FrameGraphTexture::Usage::COLOR_ATTACHMENT);
|
||||
|
||||
builder.declareRenderPass("Picking Render Target", {
|
||||
.attachments = {.color = { data.picking }, .depth = data.depth },
|
||||
.clearFlags = TargetBufferFlags::COLOR0 | TargetBufferFlags::DEPTH
|
||||
});
|
||||
},
|
||||
[=, passBuilder = passBuilder](FrameGraphResources const& resources,
|
||||
auto const&, DriverApi& driver) mutable {
|
||||
Variant pickingVariant(Variant::DEPTH_VARIANT);
|
||||
pickingVariant.setPicking(true);
|
||||
|
||||
// bind the per-view descriptorSet that is used for the structure pass
|
||||
getStructureDescriptorSet().bind(driver);
|
||||
|
||||
auto [target, params] = resources.getRenderPassInfo();
|
||||
passBuilder.renderFlags(structureRenderFlags);
|
||||
passBuilder.variant(pickingVariant);
|
||||
passBuilder.commandTypeFlags(RenderPass::CommandTypeFlags::DEPTH);
|
||||
|
||||
RenderPass const pass{ passBuilder.build(mEngine, driver) };
|
||||
driver.beginRenderPass(target, params);
|
||||
pass.getExecutor().execute(mEngine, driver);
|
||||
driver.endRenderPass();
|
||||
});
|
||||
|
||||
return pickingRenderPass->picking;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
FrameGraphId<FrameGraphTexture> PostProcessManager::ssr(FrameGraph& fg,
|
||||
@@ -858,7 +918,8 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::screenSpaceAmbientOcclusion(
|
||||
});
|
||||
},
|
||||
[=](FrameGraphResources const& resources, auto const& data, DriverApi& driver) {
|
||||
bindPostProcessDescriptorSet(driver);
|
||||
// bind the per-view descriptorSet that is used for the structure pass
|
||||
getStructureDescriptorSet().bind(driver);
|
||||
|
||||
auto depth = resources.getTexture(data.depth);
|
||||
auto ssao = resources.getRenderPassInfo();
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
#include "ds/PostProcessDescriptorSet.h"
|
||||
#include "ds/SsrPassDescriptorSet.h"
|
||||
#include "ds/StructureDescriptorSet.h"
|
||||
#include "ds/TypedUniformBuffer.h"
|
||||
|
||||
#include "materials/StaticMaterialInfo.h"
|
||||
@@ -104,6 +105,10 @@ public:
|
||||
RenderPassBuilder const& passBuilder, uint8_t structureRenderFlags,
|
||||
uint32_t width, uint32_t height, StructurePassConfig const& config) noexcept;
|
||||
|
||||
FrameGraphId<FrameGraphTexture> transparentPicking(FrameGraph& fg,
|
||||
RenderPassBuilder const& passBuilder, uint8_t structureRenderFlags,
|
||||
uint32_t width, uint32_t height, float scale) noexcept;
|
||||
|
||||
// reflections pass
|
||||
FrameGraphId<FrameGraphTexture> ssr(FrameGraph& fg,
|
||||
RenderPassBuilder const& passBuilder,
|
||||
@@ -393,6 +398,8 @@ public:
|
||||
ColorGradingConfig const& colorGradingConfig, VignetteOptions const& vignetteOptions,
|
||||
uint32_t width, uint32_t height) noexcept;
|
||||
|
||||
StructureDescriptorSet& getStructureDescriptorSet() const noexcept { return mStructureDescriptorSet; }
|
||||
|
||||
private:
|
||||
backend::RenderPrimitiveHandle mFullScreenQuadRph;
|
||||
backend::VertexBufferInfoHandle mFullScreenQuadVbih;
|
||||
@@ -402,6 +409,7 @@ private:
|
||||
|
||||
mutable SsrPassDescriptorSet mSsrPassDescriptorSet;
|
||||
mutable PostProcessDescriptorSet mPostProcessDescriptorSet;
|
||||
mutable StructureDescriptorSet mStructureDescriptorSet;
|
||||
|
||||
struct BilateralPassConfig {
|
||||
uint8_t kernelSize = 11;
|
||||
|
||||
@@ -28,9 +28,19 @@
|
||||
#include "details/Fence.h"
|
||||
#include "details/Scene.h"
|
||||
#include "details/SwapChain.h"
|
||||
#include "details/Texture.h"
|
||||
#include "details/View.h"
|
||||
|
||||
#include "ds/StructureDescriptorSet.h"
|
||||
|
||||
#include "fg/FrameGraph.h"
|
||||
#include "fg/FrameGraphId.h"
|
||||
#include "fg/FrameGraphResources.h"
|
||||
#include "fg/FrameGraphTexture.h"
|
||||
|
||||
#include <private/filament/Variant.h>
|
||||
|
||||
#include <private/utils/Tracing.h>
|
||||
|
||||
#include <filament/Camera.h>
|
||||
#include <filament/Fence.h>
|
||||
#include <filament/Options.h>
|
||||
@@ -41,23 +51,17 @@
|
||||
#include <backend/Handle.h>
|
||||
#include <backend/PixelBufferDescriptor.h>
|
||||
|
||||
#include "fg/FrameGraph.h"
|
||||
#include "fg/FrameGraphId.h"
|
||||
#include "fg/FrameGraphResources.h"
|
||||
#include "fg/FrameGraphTexture.h"
|
||||
|
||||
#include <math/vec2.h>
|
||||
#include <math/vec3.h>
|
||||
#include <math/mat4.h>
|
||||
|
||||
#include <private/utils/Tracing.h>
|
||||
|
||||
#include <utils/architecture.h>
|
||||
#include <utils/Allocator.h>
|
||||
#include <utils/JobSystem.h>
|
||||
#include <utils/Logger.h>
|
||||
#include <utils/Panic.h>
|
||||
#include <utils/compiler.h>
|
||||
#include <utils/debug.h>
|
||||
#include <utils/ostream.h>
|
||||
|
||||
#include <chrono>
|
||||
#include <limits>
|
||||
@@ -198,6 +202,7 @@ TextureFormat FRenderer::getHdrFormat(const FView& view, bool const translucent)
|
||||
return mHdrQualityHigh;
|
||||
}
|
||||
}
|
||||
return mHdrQualityMedium;
|
||||
}
|
||||
|
||||
TextureFormat FRenderer::getLdrFormat(bool const translucent) const noexcept {
|
||||
@@ -230,7 +235,7 @@ void FRenderer::initializeClearFlags() noexcept {
|
||||
mClearFlags = getClearFlags();
|
||||
}
|
||||
|
||||
void FRenderer::setPresentationTime(int64_t const monotonic_clock_ns) {
|
||||
void FRenderer::setPresentationTime(int64_t const monotonic_clock_ns) const {
|
||||
FEngine::DriverApi& driver = mEngine.getDriverApi();
|
||||
driver.setPresentationTime(monotonic_clock_ns);
|
||||
}
|
||||
@@ -301,7 +306,7 @@ bool FRenderer::beginFrame(FSwapChain* swapChain, uint64_t vsyncSteadyClockTimeN
|
||||
using namespace std::chrono;
|
||||
const steady_clock::time_point now{ steady_clock::now() };
|
||||
const steady_clock::time_point userVsync{ steady_clock::duration(vsyncSteadyClockTimeNano) };
|
||||
const time_point<steady_clock> appVsync(vsyncSteadyClockTimeNano ? userVsync : now);
|
||||
const time_point appVsync(vsyncSteadyClockTimeNano ? userVsync : now);
|
||||
|
||||
mFrameId++;
|
||||
mViewRenderedCount = 0;
|
||||
@@ -341,7 +346,7 @@ bool FRenderer::beginFrame(FSwapChain* swapChain, uint64_t vsyncSteadyClockTimeN
|
||||
* to ignore the return value and render the frame anyway -- which is perfectly fine.
|
||||
* The remaining work will be done when the first render() call is made.
|
||||
*/
|
||||
auto beginFrameInternal = [this, appVsync, swapChain]() {
|
||||
auto beginFrameInternal = [this, appVsync, swapChain] {
|
||||
FEngine& engine = mEngine;
|
||||
FEngine::DriverApi& driver = engine.getDriverApi();
|
||||
|
||||
@@ -398,7 +403,7 @@ void FRenderer::endFrame() {
|
||||
FEngine& engine = mEngine;
|
||||
FEngine::DriverApi& driver = engine.getDriverApi();
|
||||
|
||||
if (UTILS_HAS_THREADING) {
|
||||
if constexpr (UTILS_HAS_THREADING) {
|
||||
// on debug builds this helps to catch cases where we're writing to
|
||||
// the buffer form another thread, which is currently not allowed.
|
||||
driver.debugThreading();
|
||||
@@ -441,7 +446,9 @@ void FRenderer::endFrame() {
|
||||
js.waitAndRelease(job);
|
||||
}
|
||||
|
||||
void FRenderer::readPixels(uint32_t const xoffset, uint32_t const yoffset, uint32_t const width, uint32_t const height,
|
||||
void FRenderer::readPixels(
|
||||
uint32_t const xoffset, uint32_t const yoffset,
|
||||
uint32_t const width, uint32_t const height,
|
||||
PixelBufferDescriptor&& buffer) {
|
||||
|
||||
const bool withinFrame = mSwapChain != nullptr;
|
||||
@@ -453,8 +460,9 @@ void FRenderer::readPixels(uint32_t const xoffset, uint32_t const yoffset, uint3
|
||||
xoffset, yoffset, width, height, std::move(buffer));
|
||||
}
|
||||
|
||||
void FRenderer::readPixels(FRenderTarget* renderTarget,
|
||||
uint32_t const xoffset, uint32_t const yoffset, uint32_t const width, uint32_t const height,
|
||||
void FRenderer::readPixels(FRenderTarget const* renderTarget,
|
||||
uint32_t const xoffset, uint32_t const yoffset,
|
||||
uint32_t const width, uint32_t const height,
|
||||
PixelBufferDescriptor&& buffer) {
|
||||
|
||||
// TODO: change the following to an assert when client call sites have addressed the issue.
|
||||
@@ -795,6 +803,24 @@ void FRenderer::renderJob(RootArenaScope& rootArenaScope, FView& view) {
|
||||
|
||||
view.prepareUpscaler(scale, taaOptions, dsrOptions);
|
||||
|
||||
// Set the PER_VIEW UBO for the passes that use the user materials, but are not the color pass
|
||||
// (e.g. structure, ssao). The PER_VIEW UBO may be different because these passes don't run
|
||||
// at the same resolution. We set only the values that are relevant to both user-materials
|
||||
// and the concerned passes. The PER_VIEW UBO contains data that is needed by the user
|
||||
// materials public APIs.
|
||||
StructureDescriptorSet& descriptorSet = ppm.getStructureDescriptorSet();
|
||||
descriptorSet.prepareCamera(engine, cameraInfo);
|
||||
descriptorSet.prepareTime(engine, getShaderUserTime());
|
||||
descriptorSet.prepareViewport(svp, {
|
||||
int32_t(float(xvp.left) * aoOptions.resolution),
|
||||
int32_t(float(xvp.bottom) * aoOptions.resolution),
|
||||
uint32_t(float(xvp.width) * aoOptions.resolution),
|
||||
uint32_t(float(xvp.height) * aoOptions.resolution) });
|
||||
//descriptorSet.prepareLodBias(); // FIXME: we need to do that too
|
||||
descriptorSet.prepareMaterialGlobals(view.getMaterialGlobals());
|
||||
descriptorSet.commit(driver);
|
||||
|
||||
|
||||
/*
|
||||
* Allocate command buffer
|
||||
*/
|
||||
@@ -938,46 +964,6 @@ void FRenderer::renderJob(RootArenaScope& rootArenaScope, FView& view) {
|
||||
passBuilder.camera(cameraInfo);
|
||||
passBuilder.geometry(scene.getRenderableData(), view.getVisibleRenderables());
|
||||
|
||||
// view set-ups that need to happen before rendering
|
||||
fg.addTrivialSideEffectPass("Prepare View Uniforms",
|
||||
[=, &view, &engine](DriverApi& driver) {
|
||||
view.prepareCamera(engine, cameraInfo);
|
||||
|
||||
// The code here is a little fragile. In theory, we need to call prepareViewport()
|
||||
// for each render pass, because the viewport parameters depend on the resolution.
|
||||
// However, in practice, we only have two resolutions: the color pass resolution,
|
||||
// and the structure pass which is governed by aoOptions.resolution (this could
|
||||
// change in the future).
|
||||
// So here we set the parameters for the structure pass and SSAO passes which
|
||||
// are always done first. The SSR pass will also use these parameters which
|
||||
// is wrong if it doesn't run at the same resolution as SSAO.
|
||||
// prepareViewport() is called again during the color pass, which resets the
|
||||
// values correctly for the Color pass, however, this will be again wrong
|
||||
// for passes that come after the Color pass, such as DoF.
|
||||
//
|
||||
// The solution is to call prepareViewport() for each pass, really (so we should
|
||||
// move it to its own UBO).
|
||||
//
|
||||
// The reason why this bug is acceptable is that the viewport parameters are
|
||||
// currently only used for generating noise, so it's not too bad.
|
||||
|
||||
// note: aoOptions.resolution is either 1.0 or 0.5, and the result is then
|
||||
// guaranteed to be an integer (because xvp is a multiple of 16).
|
||||
view.prepareViewport(svp,
|
||||
filament::Viewport{
|
||||
int32_t(float(xvp.left ) * aoOptions.resolution),
|
||||
int32_t(float(xvp.bottom) * aoOptions.resolution),
|
||||
uint32_t(float(xvp.width ) * aoOptions.resolution),
|
||||
uint32_t(float(xvp.height) * aoOptions.resolution)});
|
||||
|
||||
// this needs to reset the sampler that are only set in RendererUtils::colorPass(), because
|
||||
// this descriptor-set is also used for ssr/picking/structure and these could be stale
|
||||
// it would be better to use a separate desriptor-set for those two cases so that we don't
|
||||
// have to do this
|
||||
view.unbindSamplers(engine);
|
||||
view.commitUniformsAndSamplers(driver);
|
||||
});
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
// structure pass -- automatically culled if not used
|
||||
// Currently it consists of a simple depth pass.
|
||||
@@ -998,68 +984,20 @@ void FRenderer::renderJob(RootArenaScope& rootArenaScope, FView& view) {
|
||||
|
||||
if (view.hasPicking()) {
|
||||
if (view.isTransparentPickingEnabled()) {
|
||||
struct PickingRenderPassData {
|
||||
FrameGraphId<FrameGraphTexture> depth;
|
||||
FrameGraphId<FrameGraphTexture> picking;
|
||||
};
|
||||
auto& pickingRenderPass = fg.addPass<PickingRenderPassData>("Picking Render Pass",
|
||||
[&](FrameGraph::Builder& builder, auto& data) {
|
||||
bool const isFL0 = mEngine.getDriverApi().getFeatureLevel() ==
|
||||
FeatureLevel::FEATURE_LEVEL_0;
|
||||
|
||||
// TODO: Specify the precision for picking pass
|
||||
uint32_t const width = std::max(32u,
|
||||
(uint32_t)std::ceil(float(svp.width) * aoOptions.resolution));
|
||||
uint32_t const height = std::max(32u,
|
||||
(uint32_t)std::ceil(float(svp.height) * aoOptions.resolution));
|
||||
data.depth = builder.createTexture("Depth Buffer", {
|
||||
.width = width, .height = height,
|
||||
.format = isFL0 ? TextureFormat::DEPTH24 : TextureFormat::DEPTH32F });
|
||||
|
||||
data.depth = builder.write(data.depth,
|
||||
FrameGraphTexture::Usage::DEPTH_ATTACHMENT);
|
||||
|
||||
data.picking = builder.createTexture("Picking Buffer", {
|
||||
.width = width, .height = height,
|
||||
.format = isFL0 ? TextureFormat::RGBA8 : TextureFormat::RG32F });
|
||||
|
||||
data.picking = builder.write(data.picking,
|
||||
FrameGraphTexture::Usage::COLOR_ATTACHMENT);
|
||||
|
||||
builder.declareRenderPass("Picking Render Target", {
|
||||
.attachments = {.color = { data.picking }, .depth = data.depth },
|
||||
.clearFlags = TargetBufferFlags::COLOR0 | TargetBufferFlags::DEPTH
|
||||
});
|
||||
},
|
||||
[=, passBuilder = passBuilder](FrameGraphResources const& resources,
|
||||
auto const& data, DriverApi& driver) mutable {
|
||||
Variant pickingVariant(Variant::DEPTH_VARIANT);
|
||||
pickingVariant.setPicking(true);
|
||||
|
||||
auto out = resources.getRenderPassInfo();
|
||||
passBuilder.renderFlags(renderFlags);
|
||||
passBuilder.variant(pickingVariant);
|
||||
passBuilder.commandTypeFlags(RenderPass::CommandTypeFlags::DEPTH);
|
||||
|
||||
RenderPass const pass{ passBuilder.build(mEngine, driver) };
|
||||
driver.beginRenderPass(out.target, out.params);
|
||||
pass.getExecutor().execute(mEngine, driver);
|
||||
driver.endRenderPass();
|
||||
});
|
||||
picking = pickingRenderPass->picking;
|
||||
picking = ppm.transparentPicking(fg,
|
||||
passBuilder, renderFlags, svp.width, svp.height, aoOptions.resolution);
|
||||
}
|
||||
|
||||
struct PickingResolvePassData {
|
||||
FrameGraphId<FrameGraphTexture> picking;
|
||||
};
|
||||
fg.addPass<PickingResolvePassData>(
|
||||
"Picking Resolve Pass",
|
||||
fg.addPass<PickingResolvePassData>("Picking Resolve Pass",
|
||||
[&](FrameGraph::Builder& builder, auto& data) {
|
||||
// Note that BLIT_SRC is needed because this texture will be read later (via
|
||||
// readPixels()).
|
||||
data.picking =
|
||||
builder.read(picking, FrameGraphTexture::Usage::COLOR_ATTACHMENT |
|
||||
FrameGraphTexture::Usage::BLIT_SRC);
|
||||
data.picking = builder.read(picking,
|
||||
FrameGraphTexture::Usage::COLOR_ATTACHMENT |
|
||||
FrameGraphTexture::Usage::BLIT_SRC);
|
||||
builder.declareRenderPass("Picking Resolve Target", {
|
||||
.attachments = { .color = { data.picking }}
|
||||
});
|
||||
@@ -1067,23 +1005,21 @@ void FRenderer::renderJob(RootArenaScope& rootArenaScope, FView& view) {
|
||||
},
|
||||
[=, &view](FrameGraphResources const& resources,
|
||||
auto const&, DriverApi& driver) mutable {
|
||||
auto out = resources.getRenderPassInfo();
|
||||
view.executePickingQueries(driver, out.target, scale * aoOptions.resolution);
|
||||
auto [target, params] = resources.getRenderPassInfo();
|
||||
view.executePickingQueries(driver, target, scale * aoOptions.resolution);
|
||||
});
|
||||
}
|
||||
|
||||
// Store this frame's camera projection in the frame history.
|
||||
// TODO: We do this after we're configured the structure and ssao passes;
|
||||
// but I'm not 100% sure this should be done before or after.
|
||||
if (UTILS_UNLIKELY(taaOptions.enabled)) {
|
||||
// Apply the TAA jitter to everything after the structure pass, starting with the color pass.
|
||||
ppm.TaaJitterCamera(svp, taaOptions, view.getFrameHistory(),
|
||||
&FrameHistoryEntry::taa, &cameraInfo);
|
||||
|
||||
fg.addTrivialSideEffectPass("Jitter Camera",
|
||||
[&engine, &cameraInfo, &descriptorSet = view.getColorPassDescriptorSet()]
|
||||
(DriverApi& driver) {
|
||||
descriptorSet.prepareCamera(engine, cameraInfo);
|
||||
descriptorSet.commit(driver);
|
||||
});
|
||||
// this just re-set the color pass UBO content
|
||||
view.prepareCamera(engine, cameraInfo);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
@@ -1143,7 +1079,7 @@ void FRenderer::renderJob(RootArenaScope& rootArenaScope, FView& view) {
|
||||
passBuilder.customCommand(3,
|
||||
RenderPass::Pass::BLENDED,
|
||||
RenderPass::CustomCommand::EPILOG,
|
||||
0, [&ppm, &driver, colorGradingConfigForColor]() {
|
||||
0, [&ppm, &driver, colorGradingConfigForColor] {
|
||||
ppm.colorGradingSubpass(driver, colorGradingConfigForColor);
|
||||
});
|
||||
} else if (colorGradingConfig.customResolve) {
|
||||
@@ -1151,7 +1087,7 @@ void FRenderer::renderJob(RootArenaScope& rootArenaScope, FView& view) {
|
||||
passBuilder.customCommand(3,
|
||||
RenderPass::Pass::BLENDED,
|
||||
RenderPass::CustomCommand::EPILOG,
|
||||
0, [&ppm, &driver]() {
|
||||
0, [&ppm, &driver] {
|
||||
ppm.customResolveSubpass(driver);
|
||||
});
|
||||
}
|
||||
@@ -1222,8 +1158,7 @@ void FRenderer::renderJob(RootArenaScope& rootArenaScope, FView& view) {
|
||||
|
||||
// We use a framegraph pass to wait for froxelization to finish (so it can be done
|
||||
// in parallel with .compile()
|
||||
auto sync = view.getFroxelizerSync();
|
||||
if (sync) {
|
||||
if (auto sync = view.getFroxelizerSync()) {
|
||||
js.waitAndRelease(sync);
|
||||
view.commitFroxels(driver);
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@ public:
|
||||
void renderStandaloneView(FView const* view);
|
||||
|
||||
|
||||
void setPresentationTime(int64_t monotonic_clock_ns);
|
||||
void setPresentationTime(int64_t monotonic_clock_ns) const;
|
||||
|
||||
void setVsyncTime(uint64_t steadyClockTimeNano) noexcept;
|
||||
|
||||
@@ -108,7 +108,7 @@ public:
|
||||
backend::PixelBufferDescriptor&& buffer);
|
||||
|
||||
// read pixel from a rendertarget. must be called between beginFrame/enfFrame.
|
||||
void readPixels(FRenderTarget* renderTarget,
|
||||
void readPixels(FRenderTarget const* renderTarget,
|
||||
uint32_t xoffset, uint32_t yoffset, uint32_t width, uint32_t height,
|
||||
backend::PixelBufferDescriptor&& buffer);
|
||||
|
||||
|
||||
@@ -854,6 +854,7 @@ void FView::prepare(FEngine& engine, DriverApi& driver, RootArenaScope& rootAren
|
||||
auto const fogTransform = tcm.getWorldTransformAccurate(tcm.getInstance(mFogEntity));
|
||||
|
||||
auto& colorPassDescriptorSet = getColorPassDescriptorSet();
|
||||
colorPassDescriptorSet.prepareCamera(engine, cameraInfo);
|
||||
colorPassDescriptorSet.prepareTime(engine, userTime);
|
||||
colorPassDescriptorSet.prepareFog(engine, cameraInfo, fogTransform, mFogOptions,
|
||||
scene->getIndirectLight());
|
||||
|
||||
@@ -102,6 +102,7 @@ class FScene;
|
||||
|
||||
class FView : public View {
|
||||
public:
|
||||
using MaterialGlobals = std::array<math::float4, 4>;
|
||||
using Range = utils::Range<uint32_t>;
|
||||
|
||||
explicit FView(FEngine& engine);
|
||||
@@ -483,6 +484,8 @@ public:
|
||||
return mFrameGraphViewerViewHandle;
|
||||
}
|
||||
|
||||
MaterialGlobals getMaterialGlobals() const { return mMaterialGlobals; }
|
||||
|
||||
private:
|
||||
struct FPickingQuery : public PickingQuery {
|
||||
private:
|
||||
@@ -609,12 +612,12 @@ private:
|
||||
|
||||
std::unique_ptr<ShadowMapManager> mShadowMapManager;
|
||||
|
||||
std::array<math::float4, 4> mMaterialGlobals = {{
|
||||
{ 0, 0, 0, 1 },
|
||||
{ 0, 0, 0, 1 },
|
||||
{ 0, 0, 0, 1 },
|
||||
{ 0, 0, 0, 1 },
|
||||
}};
|
||||
MaterialGlobals mMaterialGlobals = {{
|
||||
{ 0, 0, 0, 1 },
|
||||
{ 0, 0, 0, 1 },
|
||||
{ 0, 0, 0, 1 },
|
||||
{ 0, 0, 0, 1 },
|
||||
}};
|
||||
|
||||
fgviewer::ViewHandle mFrameGraphViewerViewHandle;
|
||||
|
||||
|
||||
@@ -73,8 +73,7 @@ DescriptorSet& DescriptorSet::operator=(DescriptorSet&& rhs) noexcept {
|
||||
|
||||
void DescriptorSet::terminate(FEngine::DriverApi& driver) noexcept {
|
||||
if (mDescriptorSetHandle) {
|
||||
driver.destroyDescriptorSet(mDescriptorSetHandle);
|
||||
mDescriptorSetHandle.clear();
|
||||
driver.destroyDescriptorSet(std::move(mDescriptorSetHandle));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,9 @@
|
||||
#include <private/filament/EngineEnums.h>
|
||||
#include <private/filament/UibStructs.h>
|
||||
|
||||
#include <utils/compiler.h>
|
||||
#include <utils/debug.h>
|
||||
|
||||
#include <math/vec4.h>
|
||||
|
||||
#include <array>
|
||||
@@ -33,15 +36,24 @@ namespace filament {
|
||||
using namespace backend;
|
||||
using namespace math;
|
||||
|
||||
StructureDescriptorSet::StructureDescriptorSet(FEngine& engine) noexcept
|
||||
: mDescriptorSetLayout(engine.getPerViewDescriptorSetLayoutDepthVariant()),
|
||||
mUniforms(engine.getDriverApi()) {
|
||||
StructureDescriptorSet::StructureDescriptorSet() noexcept = default;
|
||||
|
||||
StructureDescriptorSet::~StructureDescriptorSet() noexcept {
|
||||
assert_invariant(!mDescriptorSet.getHandle());
|
||||
}
|
||||
|
||||
void StructureDescriptorSet::init(FEngine& engine) noexcept {
|
||||
|
||||
mUniforms.init(engine.getDriverApi());
|
||||
|
||||
mDescriptorSetLayout = &engine.getPerViewDescriptorSetLayoutDepthVariant();
|
||||
|
||||
// create the descriptor-set from the layout
|
||||
mDescriptorSet = DescriptorSet{
|
||||
"StructureDescriptorSet", mDescriptorSetLayout };
|
||||
"StructureDescriptorSet", *mDescriptorSetLayout };
|
||||
|
||||
// initialize the descriptor-set
|
||||
mDescriptorSet.setBuffer(mDescriptorSetLayout, +PerViewBindingPoints::FRAME_UNIFORMS,
|
||||
mDescriptorSet.setBuffer(*mDescriptorSetLayout, +PerViewBindingPoints::FRAME_UNIFORMS,
|
||||
mUniforms.getUboHandle(), 0, sizeof(PerViewUib));
|
||||
}
|
||||
|
||||
@@ -53,7 +65,11 @@ void StructureDescriptorSet::terminate(DriverApi& driver) {
|
||||
void StructureDescriptorSet::commit(DriverApi& driver) noexcept {
|
||||
driver.updateBufferObject(mUniforms.getUboHandle(),
|
||||
mUniforms.toBufferDescriptor(driver), 0);
|
||||
mDescriptorSet.commit(mDescriptorSetLayout, driver);
|
||||
|
||||
assert_invariant(mDescriptorSetLayout);
|
||||
if (mDescriptorSetLayout) {
|
||||
mDescriptorSet.commit(*mDescriptorSetLayout, driver);
|
||||
}
|
||||
}
|
||||
|
||||
void StructureDescriptorSet::bind(DriverApi& driver) const noexcept {
|
||||
|
||||
@@ -38,7 +38,10 @@ struct CameraInfo;
|
||||
|
||||
class StructureDescriptorSet {
|
||||
public:
|
||||
explicit StructureDescriptorSet(FEngine& engine) noexcept;
|
||||
StructureDescriptorSet() noexcept;
|
||||
~StructureDescriptorSet() noexcept;
|
||||
|
||||
void init(FEngine& engine) noexcept;
|
||||
|
||||
void terminate(backend::DriverApi& driver);
|
||||
|
||||
@@ -61,7 +64,7 @@ public:
|
||||
void prepareMaterialGlobals(std::array<math::float4, 4> const& materialGlobals) noexcept;
|
||||
|
||||
private:
|
||||
DescriptorSetLayout const& mDescriptorSetLayout;
|
||||
DescriptorSetLayout const* mDescriptorSetLayout = nullptr;
|
||||
DescriptorSet mDescriptorSet;
|
||||
TypedUniformBuffer<PerViewUib> mUniforms;
|
||||
};
|
||||
|
||||
@@ -21,7 +21,11 @@
|
||||
|
||||
#include <backend/BufferDescriptor.h>
|
||||
#include <backend/DriverApiForward.h>
|
||||
#include <backend/DriverEnums.h>
|
||||
#include <backend/Handle.h>
|
||||
#include <utils/debug.h>
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
@@ -31,7 +35,14 @@ template<typename T, size_t N = 1>
|
||||
class TypedUniformBuffer {
|
||||
public:
|
||||
|
||||
TypedUniformBuffer() noexcept = default;
|
||||
|
||||
explicit TypedUniformBuffer(backend::DriverApi& driver) noexcept {
|
||||
init(driver);
|
||||
}
|
||||
|
||||
void init(backend::DriverApi& driver) noexcept {
|
||||
assert_invariant(!mUboHandle);
|
||||
mUboHandle = driver.createBufferObject(
|
||||
mTypedBuffer.getSize(),
|
||||
backend::BufferObjectBinding::UNIFORM,
|
||||
@@ -39,7 +50,12 @@ public:
|
||||
}
|
||||
|
||||
void terminate(backend::DriverApi& driver) noexcept {
|
||||
driver.destroyBufferObject(mUboHandle);
|
||||
assert_invariant(mUboHandle);
|
||||
driver.destroyBufferObject(std::move(mUboHandle));
|
||||
}
|
||||
|
||||
~TypedUniformBuffer() noexcept {
|
||||
assert_invariant(!mUboHandle);
|
||||
}
|
||||
|
||||
TypedBuffer<T,N>& getTypedBuffer() noexcept {
|
||||
|
||||
Reference in New Issue
Block a user