From 02f96e2a1e2c6df9dcf33ccc7ee25ff6e6592bf5 Mon Sep 17 00:00:00 2001 From: daemyung jang Date: Mon, 17 Jan 2022 10:58:08 +0900 Subject: [PATCH] Store morph weight buffer at PrimitiveInfo to avoid dereference --- filament/src/RenderPass.cpp | 11 +++++++---- filament/src/RenderPass.h | 3 ++- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/filament/src/RenderPass.cpp b/filament/src/RenderPass.cpp index f5d9993334..6129b82d89 100644 --- a/filament/src/RenderPass.cpp +++ b/filament/src/RenderPass.cpp @@ -277,6 +277,7 @@ void RenderPass::generateCommandsImpl(uint32_t extraFlags, auto const* const UTILS_RESTRICT soaWorldAABBCenter = soa.data(); auto const* const UTILS_RESTRICT soaVisibility = soa.data(); auto const* const UTILS_RESTRICT soaPrimitives = soa.data(); + auto const* const UTILS_RESTRICT soaMorphing = soa.data(); auto const* const UTILS_RESTRICT soaVisibilityMask = soa.data(); const bool hasShadowing = renderFlags & HAS_SHADOWING; @@ -372,6 +373,7 @@ void RenderPass::generateCommandsImpl(uint32_t extraFlags, const bool writeDepthForShadowCasters = depthContainsShadowCasters & shadowCaster; const Slice& primitives = soaPrimitives[i]; + const auto& morphing = soaMorphing[i]; /* * This is our hot loop. It's written to avoid branches. @@ -385,6 +387,7 @@ void RenderPass::generateCommandsImpl(uint32_t extraFlags, cmdColor.primitive.materialVariant = materialVariant; RenderPass::setupColorCommand(cmdColor, mi, inverseFrontFaces); + cmdColor.primitive.morphWeightBuffer = morphing.handle; if (UTILS_UNLIKELY(morphTargetBuffer)) { cmdColor.primitive.morphTargetBuffer = morphTargetBuffer->getHwHandle(); } @@ -477,6 +480,7 @@ void RenderPass::generateCommandsImpl(uint32_t extraFlags, cmdDepth.primitive.mi = mi; cmdDepth.primitive.rasterState.culling = mi->getCullingMode(); + cmdDepth.primitive.morphWeightBuffer = morphing.handle; if (UTILS_UNLIKELY(morphTargetBuffer)) { cmdDepth.primitive.morphTargetBuffer = morphTargetBuffer->getHwHandle(); } @@ -538,7 +542,6 @@ void RenderPass::Executor::recordDriverCommands(backend::DriverApi& driver, SYSTRACE_VALUE32("commandCount", last - first); auto const* const UTILS_RESTRICT soaSkinning = soa.data(); - auto const* const UTILS_RESTRICT soaMorphing = soa.data(); PolygonOffset dummyPolyOffset; PipelineState pipeline{ .polygonOffset = mPolygonOffset }; @@ -588,11 +591,11 @@ void RenderPass::Executor::recordDriverCommands(backend::DriverApi& driver, CONFIG_MAX_BONE_COUNT * sizeof(PerRenderableUibBone)); } - auto morphing = soaMorphing[info.index]; - if (UTILS_UNLIKELY(morphing.handle)) { + if (UTILS_UNLIKELY(info.morphWeightBuffer)) { // Instead of using a UBO per primitive, we could also have a single UBO for all primitives // and use bindUniformBufferRange which might be more efficient. - driver.bindUniformBuffer(BindingPoints::PER_RENDERABLE_MORPHING, morphing.handle); + driver.bindUniformBuffer(BindingPoints::PER_RENDERABLE_MORPHING, + info.morphWeightBuffer); if (UTILS_UNLIKELY(info.morphTargetBuffer)) { driver.bindSamplers(BindingPoints::PER_RENDERABLE_MORPHING, info.morphTargetBuffer); diff --git a/filament/src/RenderPass.h b/filament/src/RenderPass.h index da9cf76082..4b05453728 100644 --- a/filament/src/RenderPass.h +++ b/filament/src/RenderPass.h @@ -211,11 +211,12 @@ public: struct PrimitiveInfo { // 32 bytes FMaterialInstance const* mi = nullptr; // 8 bytes (4) backend::Handle primitiveHandle; // 4 bytes + backend::Handle morphWeightBuffer; // 4 bytes backend::Handle morphTargetBuffer; // 4 bytes backend::RasterState rasterState; // 4 bytes uint16_t index = 0; // 2 bytes Variant materialVariant; // 1 byte - uint8_t reserved[17 - sizeof(void*)] = {}; // 9 bytes (13) + uint8_t reserved[13 - sizeof(void*)] = {}; // 5 bytes (9) }; static_assert(sizeof(PrimitiveInfo) == 32);