From 84bfbac5fa1ae188a13ac7e73bb98b6572a47dcb Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Tue, 23 Oct 2018 15:49:49 -0700 Subject: [PATCH] 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. --- filament/src/Scene.cpp | 9 ++------- filament/src/View.cpp | 28 +++++++++++++++------------- filament/src/details/Scene.h | 3 +-- filament/src/details/View.h | 16 ++++++++++------ 4 files changed, 28 insertions(+), 28 deletions(-) diff --git a/filament/src/Scene.cpp b/filament/src/Scene.cpp index dee0d3fd5f..c801067bd8 100644 --- a/filament/src/Scene.cpp +++ b/filament/src/Scene.cpp @@ -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 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 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 diff --git a/filament/src/View.cpp b/filament/src/View.cpp index f5e679babd..569262e937 100644 --- a/filament/src/View.cpp +++ b/filament/src/View.cpp @@ -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(); diff --git a/filament/src/details/Scene.h b/filament/src/details/Scene.h index d330270c27..f487279dcf 100644 --- a/filament/src/details/Scene.h +++ b/filament/src/details/Scene.h @@ -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 lightUbh) noexcept; void computeBounds(Aabb& castersBox, Aabb& receiversBox, uint32_t visibleLayers) const noexcept; @@ -183,7 +183,6 @@ private: uint32_t mRenderableUBOSize = 0; Handle mRenderableUBO; // TODO: should this UBO be per-view? - Handle mLightUBO; // TODO: should this UBO be per-view? }; FILAMENT_UPCAST(Scene) diff --git a/filament/src/details/View.h b/filament/src/details/View.h index ea52e1879b..ecfbea8248 100644 --- a/filament/src/details/View.h +++ b/filament/src/details/View.h @@ -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 mPerViewSbh; Handle mPerViewUbh; + Handle mLightUbh; - UniformBuffer& getUb() const noexcept { return mPerViewUb; } - Handle getUbh() const noexcept { return mPerViewUbh; } - - SamplerBuffer& getUs() const noexcept { return mPerViewSb; } Handle getUsh() const noexcept { return mPerViewSbh; } + Handle getUbh() const noexcept { return mPerViewUbh; } + Handle 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;