move FScene::updateUBO() back to FView
it really didn't belong to FScene
This commit is contained in:
committed by
Mathias Agopian
parent
a7894b5876
commit
39bf0f0a71
@@ -18,8 +18,10 @@
|
||||
#define TNT_FILAMENT_BUFFERPOOLALLOCATOR_H
|
||||
|
||||
#include <utils/Allocator.h>
|
||||
#include <utils/compiler.h>
|
||||
#include <utils/FixedCapacityVector.h>
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#include <stdint.h>
|
||||
@@ -110,7 +112,7 @@ void* BufferPoolAllocator<POOL_SIZE, ALIGNMENT, AllocatorPolicy, LockingPolicy>:
|
||||
if (UTILS_UNLIKELY(size > mSize)) {
|
||||
clearInternal(); // free all buffers
|
||||
// round to 4K allocations to help cutting down on calling malloc.
|
||||
size_t roundedSize = ((size + sizeof(Header)) + (ALLOCATION_ROUNDING - 1)) & ~(ALLOCATION_ROUNDING - 1);
|
||||
size_t const roundedSize = ((size + sizeof(Header)) + (ALLOCATION_ROUNDING - 1)) & ~(ALLOCATION_ROUNDING - 1);
|
||||
mSize = roundedSize - sizeof(Header); // record the new buffer size
|
||||
assert_invariant(mSize >= size);
|
||||
}
|
||||
@@ -119,7 +121,7 @@ void* BufferPoolAllocator<POOL_SIZE, ALIGNMENT, AllocatorPolicy, LockingPolicy>:
|
||||
// larger than the requested size).
|
||||
if (UTILS_UNLIKELY(mEntries.empty())) {
|
||||
++mOutstandingBuffers;
|
||||
Header* p = (Header*)mAllocator.alloc(mSize + sizeof(Header), ALIGNMENT);
|
||||
Header* p = static_cast<Header*>(mAllocator.alloc(mSize + sizeof(Header), ALIGNMENT));
|
||||
p->size = mSize;
|
||||
return p + 1;
|
||||
}
|
||||
|
||||
@@ -127,9 +127,8 @@ void FInstanceBuffer::setLocalTransforms(
|
||||
memcpy(mLocalTransforms.data() + offset, localTransforms, sizeof(math::mat4f) * count);
|
||||
}
|
||||
|
||||
void FInstanceBuffer::prepare(FEngine& engine, math::mat4f const& rootTransform,
|
||||
void FInstanceBuffer::prepare(DriverApi& driver, math::mat4f const& rootTransform,
|
||||
const PerRenderableData& ubo) {
|
||||
DriverApi& driver = engine.getDriverApi();
|
||||
|
||||
// TODO: allocate this staging buffer from a pool.
|
||||
constexpr uint32_t stagingBufferSize = sizeof(PerRenderableUib);
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
|
||||
#include <filament/InstanceBuffer.h>
|
||||
|
||||
#include <backend/DriverApiForward.h>
|
||||
#include <backend/Handle.h>
|
||||
|
||||
#include <math/mat4.h>
|
||||
@@ -48,7 +49,7 @@ public:
|
||||
|
||||
void setLocalTransforms(math::mat4f const* localTransforms, size_t count, size_t offset);
|
||||
|
||||
void prepare(FEngine& engine, math::mat4f const& rootTransform, const PerRenderableData& ubo);
|
||||
void prepare(backend::DriverApi& driver, math::mat4f const& rootTransform, const PerRenderableData& ubo);
|
||||
|
||||
utils::CString const& getName() const noexcept { return mName; }
|
||||
|
||||
|
||||
@@ -17,18 +17,18 @@
|
||||
#include "details/Scene.h"
|
||||
|
||||
#include "Allocators.h"
|
||||
#include "BufferPoolAllocator.h"
|
||||
|
||||
#include "backend/Handle.h"
|
||||
#include "components/LightManager.h"
|
||||
#include "components/RenderableManager.h"
|
||||
#include "components/TransformManager.h"
|
||||
|
||||
#include "details/Engine.h"
|
||||
#include "details/InstanceBuffer.h"
|
||||
#include "details/Skybox.h"
|
||||
|
||||
#include <backend/Handle.h>
|
||||
|
||||
#include <private/filament/UibStructs.h>
|
||||
|
||||
#include <private/utils/Tracing.h>
|
||||
|
||||
#include <filament/Box.h>
|
||||
@@ -70,7 +70,7 @@ namespace filament {
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
FScene::FScene(FEngine& engine) :
|
||||
mEngine(engine), mSharedState(std::make_shared<SharedState>()) {
|
||||
mEngine(engine) {
|
||||
}
|
||||
|
||||
FScene::~FScene() noexcept = default;
|
||||
@@ -406,66 +406,6 @@ void FScene::prepareVisibleRenderables(Range<uint32_t> visibleRenderables) noexc
|
||||
}
|
||||
}
|
||||
|
||||
void FScene::updateUBOs(
|
||||
Range<uint32_t> visibleRenderables,
|
||||
Handle<HwBufferObject> renderableUbh) noexcept {
|
||||
FILAMENT_TRACING_CALL(FILAMENT_TRACING_CATEGORY_FILAMENT);
|
||||
FEngine::DriverApi& driver = mEngine.getDriverApi();
|
||||
|
||||
// don't allocate more than 16 KiB directly into the render stream
|
||||
static constexpr size_t MAX_STREAM_ALLOCATION_COUNT = 64; // 16 KiB
|
||||
const size_t count = visibleRenderables.size();
|
||||
PerRenderableData* buffer = [&]{
|
||||
if (count >= MAX_STREAM_ALLOCATION_COUNT) {
|
||||
// use the heap allocator
|
||||
auto& bufferPoolAllocator = mSharedState->mBufferPoolAllocator;
|
||||
return static_cast<PerRenderableData*>(bufferPoolAllocator.get(count * sizeof(PerRenderableData)));
|
||||
} else {
|
||||
// allocate space into the command stream directly
|
||||
return driver.allocatePod<PerRenderableData>(count);
|
||||
}
|
||||
}();
|
||||
|
||||
PerRenderableData const* const uboData = mRenderableData.data<UBO>();
|
||||
mat4f const* const worldTransformData = mRenderableData.data<WORLD_TRANSFORM>();
|
||||
|
||||
// prepare each InstanceBuffer.
|
||||
FRenderableManager::InstancesInfo const* instancesData = mRenderableData.data<INSTANCES>();
|
||||
for (uint32_t const i : visibleRenderables) {
|
||||
auto& instancesInfo = instancesData[i];
|
||||
if (UTILS_UNLIKELY(instancesInfo.buffer)) {
|
||||
instancesInfo.buffer->prepare(
|
||||
mEngine, worldTransformData[i], uboData[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// copy our data into the UBO for each visible renderable
|
||||
for (uint32_t const i : visibleRenderables) {
|
||||
buffer[i] = uboData[i];
|
||||
}
|
||||
|
||||
// We capture state shared between Scene and the update buffer callback, because the Scene could
|
||||
// be destroyed before the callback executes.
|
||||
std::weak_ptr<SharedState>* const weakShared =
|
||||
new (std::nothrow) std::weak_ptr<SharedState>(mSharedState);
|
||||
|
||||
// update the UBO
|
||||
driver.resetBufferObject(renderableUbh);
|
||||
driver.updateBufferObjectUnsynchronized(renderableUbh, {
|
||||
buffer, count * sizeof(PerRenderableData),
|
||||
+[](void* p, size_t const s, void* user) {
|
||||
std::weak_ptr<SharedState>* const weakShared =
|
||||
static_cast<std::weak_ptr<SharedState>*>(user);
|
||||
if (s >= MAX_STREAM_ALLOCATION_COUNT * sizeof(PerRenderableData)) {
|
||||
if (auto state = weakShared->lock()) {
|
||||
state->mBufferPoolAllocator.put(p);
|
||||
}
|
||||
}
|
||||
delete weakShared;
|
||||
}, weakShared
|
||||
}, 0);
|
||||
}
|
||||
|
||||
void FScene::terminate(FEngine&) {
|
||||
}
|
||||
|
||||
@@ -497,7 +437,7 @@ void FScene::prepareDynamicLights(const CameraInfo& camera,
|
||||
auto const* UTILS_RESTRICT shadowInfo = lightData.data<SHADOW_INFO>();
|
||||
for (size_t i = DIRECTIONAL_LIGHTS_COUNT, c = size; i < c; ++i) {
|
||||
const size_t gpuIndex = i - DIRECTIONAL_LIGHTS_COUNT;
|
||||
auto li = instances[i];
|
||||
auto const li = instances[i];
|
||||
lp[gpuIndex].positionFalloff = { spheres[i].xyz, lcm.getSquaredFalloffInv(li) };
|
||||
lp[gpuIndex].direction = directions[i];
|
||||
lp[gpuIndex].reserved1 = {};
|
||||
@@ -627,7 +567,7 @@ bool FScene::hasContactShadows() const noexcept {
|
||||
|
||||
// find out if at least one light has contact-shadow enabled
|
||||
// TODO: we could cache the result of this Loop in the LightManager
|
||||
auto& lcm = mEngine.getLightManager();
|
||||
auto const& lcm = mEngine.getLightManager();
|
||||
const auto *pFirst = mLightData.begin<LIGHT_INSTANCE>();
|
||||
const auto *pLast = mLightData.end<LIGHT_INSTANCE>();
|
||||
while (pFirst != pLast) {
|
||||
|
||||
@@ -26,28 +26,18 @@
|
||||
|
||||
#include "components/LightManager.h"
|
||||
#include "components/RenderableManager.h"
|
||||
#include "components/TransformManager.h"
|
||||
|
||||
#include "BufferPoolAllocator.h"
|
||||
|
||||
#include <filament/Box.h>
|
||||
#include <filament/Scene.h>
|
||||
|
||||
#include <math/mathfwd.h>
|
||||
|
||||
#include <utils/compiler.h>
|
||||
#include <utils/Entity.h>
|
||||
#include <utils/Slice.h>
|
||||
#include <utils/StructureOfArrays.h>
|
||||
#include <utils/Range.h>
|
||||
#include <utils/debug.h>
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include <tsl/robin_set.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace filament {
|
||||
|
||||
struct CameraInfo;
|
||||
@@ -136,14 +126,14 @@ public:
|
||||
RenderableSoa const& getRenderableData() const noexcept { return mRenderableData; }
|
||||
RenderableSoa& getRenderableData() noexcept { return mRenderableData; }
|
||||
|
||||
static inline uint32_t getPrimitiveCount(RenderableSoa const& soa,
|
||||
static uint32_t getPrimitiveCount(RenderableSoa const& soa,
|
||||
uint32_t const first, uint32_t const last) noexcept {
|
||||
// the caller must guarantee that last is dereferenceable
|
||||
return soa.elementAt<SUMMED_PRIMITIVE_COUNT>(last) -
|
||||
soa.elementAt<SUMMED_PRIMITIVE_COUNT>(first);
|
||||
}
|
||||
|
||||
static inline uint32_t getPrimitiveCount(RenderableSoa const& soa, uint32_t const last) noexcept {
|
||||
static uint32_t getPrimitiveCount(RenderableSoa const& soa, uint32_t const last) noexcept {
|
||||
// the caller must guarantee that last is dereferenceable
|
||||
return soa.elementAt<SUMMED_PRIMITIVE_COUNT>(last);
|
||||
}
|
||||
@@ -186,9 +176,6 @@ public:
|
||||
LightSoa const& getLightData() const noexcept { return mLightData; }
|
||||
LightSoa& getLightData() noexcept { return mLightData; }
|
||||
|
||||
void updateUBOs(utils::Range<uint32_t> visibleRenderables,
|
||||
backend::Handle<backend::HwBufferObject> renderableUbh) noexcept;
|
||||
|
||||
bool hasContactShadows() const noexcept;
|
||||
|
||||
private:
|
||||
@@ -230,12 +217,6 @@ private:
|
||||
RenderableSoa mRenderableData;
|
||||
LightSoa mLightData;
|
||||
bool mHasContactShadows = false;
|
||||
|
||||
// State shared between Scene and driver callbacks.
|
||||
struct SharedState {
|
||||
BufferPoolAllocator<3> mBufferPoolAllocator = {};
|
||||
};
|
||||
std::shared_ptr<SharedState> mSharedState;
|
||||
};
|
||||
|
||||
FILAMENT_DOWNCAST(Scene)
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "details/View.h"
|
||||
|
||||
#include "Allocators.h"
|
||||
#include "BufferPoolAllocator.h"
|
||||
#include "Culler.h"
|
||||
#include "DebugRegistry.h"
|
||||
#include "FrameHistory.h"
|
||||
@@ -27,8 +28,11 @@
|
||||
#include "ShadowMap.h"
|
||||
#include "ShadowMapManager.h"
|
||||
|
||||
#include "components/TransformManager.h"
|
||||
|
||||
#include "details/Engine.h"
|
||||
#include "details/IndirectLight.h"
|
||||
#include "details/InstanceBuffer.h"
|
||||
#include "details/RenderTarget.h"
|
||||
#include "details/Renderer.h"
|
||||
#include "details/Scene.h"
|
||||
@@ -54,6 +58,7 @@
|
||||
#include <utils/compiler.h>
|
||||
#include <utils/debug.h>
|
||||
#include <utils/Panic.h>
|
||||
#include <utils/Range.h>
|
||||
#include <utils/Slice.h>
|
||||
#include <utils/Zip2Iterator.h>
|
||||
|
||||
@@ -71,6 +76,7 @@
|
||||
#include <chrono>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <new>
|
||||
#include <ratio>
|
||||
#include <utility>
|
||||
|
||||
@@ -93,7 +99,8 @@ FView::FView(FEngine& engine)
|
||||
mUniforms(engine.getDriverApi()),
|
||||
mColorPassDescriptorSet{
|
||||
{ engine, false, mUniforms },
|
||||
{ engine, true, mUniforms } }
|
||||
{ engine, true, mUniforms } },
|
||||
mSharedState(std::make_shared<SharedState>())
|
||||
{
|
||||
DriverApi& driver = engine.getDriverApi();
|
||||
|
||||
@@ -766,7 +773,7 @@ void FView::prepare(FEngine& engine, DriverApi& driver, RootArenaScope& rootAren
|
||||
// TODO: should we shrink the underlying UBO at some point?
|
||||
}
|
||||
assert_invariant(mRenderableUbh);
|
||||
scene->updateUBOs(merged, mRenderableUbh);
|
||||
updateUBOs(driver, renderableData, merged, mRenderableUbh);
|
||||
|
||||
mCommonRenderableDescriptorSet.setBuffer(
|
||||
engine.getPerRenderableDescriptorSetLayout(),
|
||||
@@ -885,6 +892,65 @@ void FView::prepare(FEngine& engine, DriverApi& driver, RootArenaScope& rootAren
|
||||
colorPassDescriptorSet.prepareMaterialGlobals(mMaterialGlobals);
|
||||
}
|
||||
|
||||
void FView::updateUBOs(
|
||||
FEngine::DriverApi& driver,
|
||||
FScene::RenderableSoa& renderableData,
|
||||
utils::Range<uint32_t> visibleRenderables,
|
||||
Handle<HwBufferObject> renderableUbh) noexcept {
|
||||
FILAMENT_TRACING_CALL(FILAMENT_TRACING_CATEGORY_FILAMENT);
|
||||
|
||||
// don't allocate more than 16 KiB directly into the render stream
|
||||
static constexpr size_t MAX_STREAM_ALLOCATION_COUNT = 64; // 16 KiB
|
||||
const size_t count = visibleRenderables.size();
|
||||
PerRenderableData* buffer = [&]{
|
||||
if (count >= MAX_STREAM_ALLOCATION_COUNT) {
|
||||
// use the heap allocator
|
||||
auto& bufferPoolAllocator = mSharedState->mBufferPoolAllocator;
|
||||
return static_cast<PerRenderableData*>(bufferPoolAllocator.get(count * sizeof(PerRenderableData)));
|
||||
}
|
||||
// allocate space into the command stream directly
|
||||
return driver.allocatePod<PerRenderableData>(count);
|
||||
}();
|
||||
|
||||
PerRenderableData const* const uboData = renderableData.data<FScene::UBO>();
|
||||
mat4f const* const worldTransformData = renderableData.data<FScene::WORLD_TRANSFORM>();
|
||||
|
||||
// prepare each InstanceBuffer.
|
||||
FRenderableManager::InstancesInfo const* instancesData = renderableData.data<FScene::INSTANCES>();
|
||||
for (uint32_t const i : visibleRenderables) {
|
||||
auto& instancesInfo = instancesData[i];
|
||||
if (UTILS_UNLIKELY(instancesInfo.buffer)) {
|
||||
instancesInfo.buffer->prepare(driver, worldTransformData[i], uboData[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// copy our data into the UBO for each visible renderable
|
||||
for (uint32_t const i : visibleRenderables) {
|
||||
buffer[i] = uboData[i];
|
||||
}
|
||||
|
||||
// We capture state shared between Scene and the update buffer callback, because the Scene could
|
||||
// be destroyed before the callback executes.
|
||||
std::weak_ptr<SharedState>* const weakShared =
|
||||
new (std::nothrow) std::weak_ptr(mSharedState);
|
||||
|
||||
// update the UBO
|
||||
driver.resetBufferObject(renderableUbh);
|
||||
driver.updateBufferObjectUnsynchronized(renderableUbh, {
|
||||
buffer, count * sizeof(PerRenderableData),
|
||||
+[](void* p, size_t const s, void* user) {
|
||||
std::weak_ptr<SharedState> const* const weakShared =
|
||||
static_cast<std::weak_ptr<SharedState>*>(user);
|
||||
if (s >= MAX_STREAM_ALLOCATION_COUNT * sizeof(PerRenderableData)) {
|
||||
if (auto state = weakShared->lock()) {
|
||||
state->mBufferPoolAllocator.put(p);
|
||||
}
|
||||
}
|
||||
delete weakShared;
|
||||
}, weakShared
|
||||
}, 0);
|
||||
}
|
||||
|
||||
void FView::computeVisibilityMasks(
|
||||
uint8_t const visibleLayers,
|
||||
uint8_t const* UTILS_RESTRICT layers,
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "downcast.h"
|
||||
|
||||
#include "Allocators.h"
|
||||
#include "BufferPoolAllocator.h"
|
||||
#include "Culler.h"
|
||||
#include "FrameHistory.h"
|
||||
#include "FrameInfo.h"
|
||||
@@ -29,8 +30,6 @@
|
||||
|
||||
#include "ds/ColorPassDescriptorSet.h"
|
||||
#include "ds/DescriptorSet.h"
|
||||
#include "ds/PostProcessDescriptorSet.h"
|
||||
#include "ds/SsrPassDescriptorSet.h"
|
||||
#include "ds/TypedUniformBuffer.h"
|
||||
|
||||
#include "components/LightManager.h"
|
||||
@@ -41,11 +40,8 @@
|
||||
#include "details/RenderTarget.h"
|
||||
#include "details/Scene.h"
|
||||
|
||||
#include <private/filament/EngineEnums.h>
|
||||
#include <private/filament/UibStructs.h>
|
||||
|
||||
#include <private/backend/DriverApi.h>
|
||||
|
||||
#include <filament/Frustum.h>
|
||||
#include <filament/Renderer.h>
|
||||
#include <filament/View.h>
|
||||
@@ -54,7 +50,6 @@
|
||||
#include <backend/Handle.h>
|
||||
|
||||
#include <utils/compiler.h>
|
||||
#include <utils/Allocator.h>
|
||||
#include <utils/Entity.h>
|
||||
#include <utils/StructureOfArrays.h>
|
||||
#include <utils/Range.h>
|
||||
@@ -68,8 +63,8 @@ namespace filament::fgviewer {
|
||||
}
|
||||
#endif
|
||||
|
||||
#include <math/scalar.h>
|
||||
#include <math/mat4.h>
|
||||
#include <math/vec4.h>
|
||||
|
||||
#include <array>
|
||||
#include <memory>
|
||||
@@ -298,7 +293,7 @@ public:
|
||||
return mGuardBandOptions;
|
||||
}
|
||||
|
||||
void setColorGrading(FColorGrading* colorGrading) noexcept {
|
||||
void setColorGrading(FColorGrading const* colorGrading) noexcept {
|
||||
mColorGrading = colorGrading == nullptr ? mDefaultColorGrading : colorGrading;
|
||||
}
|
||||
|
||||
@@ -441,9 +436,8 @@ public:
|
||||
backend::TargetBufferFlags getRenderTargetAttachmentMask() const noexcept {
|
||||
if (mRenderTarget == nullptr) {
|
||||
return backend::TargetBufferFlags::NONE;
|
||||
} else {
|
||||
return mRenderTarget->getAttachmentMask();
|
||||
}
|
||||
return mRenderTarget->getAttachmentMask();
|
||||
}
|
||||
|
||||
static void cullRenderables(utils::JobSystem& js, FScene::RenderableSoa& renderableData,
|
||||
@@ -484,7 +478,7 @@ public:
|
||||
return mFogEntity;
|
||||
}
|
||||
|
||||
TypedUniformBuffer<PerViewUib>& getFrameUniforms() noexcept {
|
||||
TypedUniformBuffer<PerViewUib>& getFrameUniforms() const noexcept {
|
||||
return mUniforms;
|
||||
}
|
||||
|
||||
@@ -508,7 +502,7 @@ private:
|
||||
PickingQueryResultCallback const callback) noexcept {
|
||||
return new(std::nothrow) FPickingQuery(x, y, handler, callback);
|
||||
}
|
||||
static void put(FPickingQuery* pQuery) noexcept {
|
||||
static void put(FPickingQuery const* pQuery) noexcept {
|
||||
delete pQuery;
|
||||
}
|
||||
mutable FPickingQuery* next = nullptr;
|
||||
@@ -518,12 +512,17 @@ private:
|
||||
backend::CallbackHandler* const handler;
|
||||
PickingQueryResultCallback const callback;
|
||||
// picking query result
|
||||
PickingQueryResult result;
|
||||
PickingQueryResult result{};
|
||||
};
|
||||
|
||||
void prepareVisibleRenderables(utils::JobSystem& js,
|
||||
Frustum const& frustum, FScene::RenderableSoa& renderableData) const noexcept;
|
||||
|
||||
void updateUBOs(backend::DriverApi& driver,
|
||||
FScene::RenderableSoa& renderableData,
|
||||
utils::Range<uint32_t> visibleRenderables,
|
||||
backend::Handle<backend::HwBufferObject> renderableUbh) noexcept;
|
||||
|
||||
static void prepareVisibleLights(FLightManager const& lcm,
|
||||
utils::Slice<float> scratch,
|
||||
math::mat4f const& viewMatrix, Frustum const& frustum,
|
||||
@@ -620,6 +619,12 @@ private:
|
||||
mutable bool mHasShadowing = false;
|
||||
mutable bool mNeedsShadowMap = false;
|
||||
|
||||
// State shared between Scene and driver callbacks.
|
||||
struct SharedState {
|
||||
BufferPoolAllocator<3> mBufferPoolAllocator = {};
|
||||
};
|
||||
std::shared_ptr<SharedState> mSharedState;
|
||||
|
||||
std::unique_ptr<ShadowMapManager> mShadowMapManager;
|
||||
|
||||
MaterialGlobals mMaterialGlobals = {{
|
||||
|
||||
Reference in New Issue
Block a user