The lights UBO must be per-View

We used to have a UBO for lights per scene, however it's better to 
have one per view, since it depends on the camera heavily and is 
limited in size.
Not doing so, could force us to upload the same UBO multiple times
per frame, for e.g. if the same scene was used in multiple views.
This commit is contained in:
Mathias Agopian
2018-10-24 15:11:54 -07:00
committed by Mathias Agopian
parent 912b301790
commit 84bfbac5fa
4 changed files with 28 additions and 28 deletions
+2 -7
View File
@@ -44,10 +44,6 @@ namespace details {
FScene::FScene(FEngine& engine) :
mEngine(engine),
mIndirectLight(engine.getDefaultIndirectLight()) {
FEngine::DriverApi& driver = engine.getDriverApi();
mLightUBO = driver.createUniformBuffer(CONFIG_MAX_LIGHT_COUNT * sizeof(LightsUib),
driver::BufferUsage::DYNAMIC);
driver.bindUniformBuffer(BindingPoints::LIGHTS, mLightUBO);
}
FScene::~FScene() noexcept = default;
@@ -215,10 +211,9 @@ void FScene::updateUBOs(utils::Range<uint32_t> visibleRenderables) noexcept {
void FScene::terminate(FEngine& engine) {
// free-up UBOs
engine.getDriverApi().destroyUniformBuffer(mRenderableUBO);
engine.getDriverApi().destroyUniformBuffer(mLightUBO);
}
void FScene::prepareDynamicLights(const CameraInfo& camera, ArenaScope& rootArena) noexcept {
void FScene::prepareDynamicLights(const CameraInfo& camera, ArenaScope& rootArena, Handle<HwUniformBuffer> lightUbh) noexcept {
FEngine::DriverApi& driver = mEngine.getDriverApi();
FLightManager& lcm = mEngine.getLightManager();
FScene::LightSoa& lightData = getLightData();
@@ -269,7 +264,7 @@ void FScene::prepareDynamicLights(const CameraInfo& camera, ArenaScope& rootAren
lp[gpuIndex].spotScaleOffset.xy = { lcm.getSpotParams(li).scaleOffset };
}
driver.updateUniformBuffer(mLightUBO, { lp, positionalLightCount * sizeof(LightsUib) });
driver.updateUniformBuffer(lightUbh, { lp, positionalLightCount * sizeof(LightsUib) });
}
// These methods need to exist so clang honors the __restrict__ keyword, which in turn
+15 -13
View File
@@ -61,34 +61,36 @@ FView::FView(FEngine& engine)
mPerViewSb(engine.getPerViewSib()),
mClipSpace01(engine.getBackend() == Backend::VULKAN),
mDirectionalShadowMap(engine) {
DriverApi& driverApi = engine.getDriverApi();
mPerViewUbh = driverApi.createUniformBuffer(mPerViewUb.getSize(), driver::BufferUsage::DYNAMIC);
mPerViewSbh = driverApi.createSamplerBuffer(mPerViewSb.getSize());
DriverApi& driver = engine.getDriverApi();
// set-up samplers
mPerViewSb.setBuffer(PerViewSib::RECORDS, mFroxelizer.getRecordBuffer());
mPerViewSb.setBuffer(PerViewSib::FROXELS, mFroxelizer.getFroxelBuffer());
if (engine.getDFG()->isValid()) {
TextureSampler sampler(TextureSampler::MagFilter::LINEAR);
mPerViewSb.setSampler(PerViewSib::IBL_DFG_LUT,
engine.getDFG()->getTexture(), sampler.getSamplerParams());
}
mPerViewSbh = driver.createSamplerBuffer(mPerViewSb.getSize());
driver.updateSamplerBuffer(mPerViewSbh, SamplerBuffer(mPerViewSb));
mIsDynamicResolutionSupported = driverApi.isFrameTimeSupported();
// allocate ubos
mPerViewUbh = driver.createUniformBuffer(mPerViewUb.getSize(), driver::BufferUsage::DYNAMIC);
mLightUbh = driver.createUniformBuffer(CONFIG_MAX_LIGHT_COUNT * sizeof(LightsUib), driver::BufferUsage::DYNAMIC);
driverApi.updateSamplerBuffer(mPerViewSbh, SamplerBuffer(mPerViewSb));
mIsDynamicResolutionSupported = driver.isFrameTimeSupported();
}
FView::~FView() noexcept = default;
void FView::terminate(FEngine& engine) {
// Here we would cleanly free resources we've allocated or we own (currently none).
DriverApi& driverApi = engine.getDriverApi();
driverApi.destroyUniformBuffer(mPerViewUbh);
driverApi.destroySamplerBuffer(mPerViewSbh);
mDirectionalShadowMap.terminate(driverApi);
mFroxelizer.terminate(driverApi);
DriverApi& driver = engine.getDriverApi();
driver.destroyUniformBuffer(mPerViewUbh);
driver.destroyUniformBuffer(mLightUbh);
driver.destroySamplerBuffer(mPerViewSbh);
mDirectionalShadowMap.terminate(driver);
mFroxelizer.terminate(driver);
}
void FView::setViewport(Viewport const& viewport) noexcept {
@@ -308,7 +310,7 @@ void FView::prepareLighting(FEngine& engine, FEngine::DriverApi& driver, ArenaSc
const CameraInfo& camera = mViewingCameraInfo;
FScene* const scene = mScene;
scene->prepareDynamicLights(camera, arena);
scene->prepareDynamicLights(camera, arena, mLightUbh);
// here the array of visible lights has been shrunk to CONFIG_MAX_LIGHT_COUNT
auto const& lightData = scene->getLightData();
+1 -2
View File
@@ -81,7 +81,7 @@ public:
void terminate(FEngine& engine);
void prepare(const math::mat4f& worldOriginTansform);
void prepareDynamicLights(const CameraInfo& camera, ArenaScope& arena) noexcept;
void prepareDynamicLights(const CameraInfo& camera, ArenaScope& arena, Handle<HwUniformBuffer> lightUbh) noexcept;
void computeBounds(Aabb& castersBox, Aabb& receiversBox, uint32_t visibleLayers) const noexcept;
@@ -183,7 +183,6 @@ private:
uint32_t mRenderableUBOSize = 0;
Handle<HwUniformBuffer> mRenderableUBO; // TODO: should this UBO be per-view?
Handle<HwUniformBuffer> mLightUBO; // TODO: should this UBO be per-view?
};
FILAMENT_UPCAST(Scene)
+10 -6
View File
@@ -216,8 +216,9 @@ private:
size_t count) const;
void bindPerViewUniformsAndSamplers(FEngine::DriverApi& driver) const noexcept {
driver.bindUniformBuffer(BindingPoints::PER_VIEW, getUbh());
driver.bindSamplers(BindingPoints::PER_VIEW, getUsh());
driver.bindUniformBuffer(BindingPoints::PER_VIEW, mPerViewUbh);
driver.bindUniformBuffer(BindingPoints::LIGHTS, mLightUbh);
driver.bindSamplers(BindingPoints::PER_VIEW, mPerViewSbh);
}
// we don't inline this one, because the function is quite large and there is not much to
@@ -229,12 +230,12 @@ private:
// these are accessed in the render loop, keep together
Handle<HwSamplerBuffer> mPerViewSbh;
Handle<HwUniformBuffer> mPerViewUbh;
Handle<HwUniformBuffer> mLightUbh;
UniformBuffer& getUb() const noexcept { return mPerViewUb; }
Handle<HwUniformBuffer> getUbh() const noexcept { return mPerViewUbh; }
SamplerBuffer& getUs() const noexcept { return mPerViewSb; }
Handle<HwSamplerBuffer> getUsh() const noexcept { return mPerViewSbh; }
Handle<HwUniformBuffer> getUbh() const noexcept { return mPerViewUbh; }
Handle<HwUniformBuffer> getLightUbh() const noexcept { return mLightUbh; }
FScene* mScene = nullptr;
FCamera* mCullingCamera = nullptr;
@@ -270,6 +271,9 @@ private:
mutable UniformBuffer mPerViewUb;
mutable SamplerBuffer mPerViewSb;
SamplerBuffer& getUs() const noexcept { return mPerViewSb; }
UniformBuffer& getUb() const noexcept { return mPerViewUb; }
utils::CString mName;
const bool mClipSpace01;