From e829d90c4a49d807be75b9d5ff2c4a963cdfc844 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Tue, 25 Jan 2022 12:18:50 -0800 Subject: [PATCH] A morphing buffer must be bound when skinning is active This is because we're using the same program variant for skinning and morphing, in the skinning-only case, the buffer won't be accessed in the shader, but it must be present. fixes #5085 --- filament/src/Engine.cpp | 19 ++++++++++ filament/src/MorphTargetBuffer.cpp | 11 +++++- filament/src/PostProcessManager.cpp | 44 +++++++++++++++--------- filament/src/PostProcessManager.h | 9 ++--- filament/src/RenderPass.cpp | 12 +++++-- filament/src/RenderPass.h | 2 +- filament/src/details/Engine.h | 12 ++++++- filament/src/details/MorphTargetBuffer.h | 2 ++ 8 files changed, 83 insertions(+), 28 deletions(-) diff --git a/filament/src/Engine.cpp b/filament/src/Engine.cpp index 1edb08a520..3311b42772 100644 --- a/filament/src/Engine.cpp +++ b/filament/src/Engine.cpp @@ -261,6 +261,20 @@ void FEngine::init() { .package(MATERIALS_DEFAULTMATERIAL_DATA, MATERIALS_DEFAULTMATERIAL_SIZE) .build(*const_cast(this))); + // create dummy textures we need throughout the engine + + mDummyOneTexture = driverApi.createTexture(SamplerType::SAMPLER_2D, 1, + TextureFormat::RGBA8, 1, 1, 1, 1, TextureUsage::DEFAULT); + + mDummyOneTextureArray = driverApi.createTexture(SamplerType::SAMPLER_2D_ARRAY, 1, + TextureFormat::RGBA8, 1, 1, 1, 1, TextureUsage::DEFAULT); + + mDummyZeroTexture = driverApi.createTexture(SamplerType::SAMPLER_2D, 1, + TextureFormat::RGBA8, 1, 1, 1, 1, TextureUsage::DEFAULT); + + // dummy textures must be initialized before this call + mDummyMorphingSamplerGroup = FMorphTargetBuffer::createDummySampleGroup(*this); + mPostProcessManager.init(); mLightManager.init(*this); mDFG = std::make_unique(*this); @@ -344,6 +358,11 @@ void FEngine::shutdown() { } cleanupResourceList(mFences); + driver.destroySamplerGroup(mDummyMorphingSamplerGroup); + driver.destroyTexture(mDummyOneTexture); + driver.destroyTexture(mDummyOneTextureArray); + driver.destroyTexture(mDummyZeroTexture); + /* * Shutdown the backend... */ diff --git a/filament/src/MorphTargetBuffer.cpp b/filament/src/MorphTargetBuffer.cpp index 43430889f3..2809aeba94 100644 --- a/filament/src/MorphTargetBuffer.cpp +++ b/filament/src/MorphTargetBuffer.cpp @@ -118,10 +118,19 @@ void FMorphTargetBuffer::terminate(FEngine& engine) { driver.destroyTexture(mTbHandle); } +Handle FMorphTargetBuffer::createDummySampleGroup(FEngine& engine) noexcept { + DriverApi& driver = engine.getDriverApi(); + Handle sgh = driver.createSamplerGroup(PerRenderPrimitiveMorphingSib::SAMPLER_COUNT); + backend::SamplerGroup group(PerRenderPrimitiveMorphingSib::SAMPLER_COUNT); + group.setSampler(PerRenderPrimitiveMorphingSib::TARGETS, engine.getOneTextureArray(), {}); + driver.updateSamplerGroup(sgh, std::move(group.toCommandStream())); + return sgh; +} + void FMorphTargetBuffer::setPositionsAt(FEngine& engine, size_t targetIndex, math::float3 const* positions, size_t count) { ASSERT_PRECONDITION(targetIndex < mCount, "targetIndex must be < count"); - auto size = getSize(mVertexCount); + const size_t size = getSize(mVertexCount); ASSERT_PRECONDITION((int)sizeof(math::float3) * count <= size, "MorphTargetBuffer (size=%lu) overflow (size=%lu)", diff --git a/filament/src/PostProcessManager.cpp b/filament/src/PostProcessManager.cpp index 7046c924b4..e84b0d7956 100644 --- a/filament/src/PostProcessManager.cpp +++ b/filament/src/PostProcessManager.cpp @@ -253,15 +253,6 @@ void PostProcessManager::init() noexcept { registerPostProcessMaterial(info.name, info.data, info.size); } - mDummyOneTexture = driver.createTexture(SamplerType::SAMPLER_2D, 1, - TextureFormat::RGBA8, 1, 1, 1, 1, TextureUsage::DEFAULT); - - mDummyOneTextureArray = driver.createTexture(SamplerType::SAMPLER_2D_ARRAY, 1, - TextureFormat::RGBA8, 1, 1, 1, 1, TextureUsage::DEFAULT); - - mDummyZeroTexture = driver.createTexture(SamplerType::SAMPLER_2D, 1, - TextureFormat::RGBA8, 1, 1, 1, 1, TextureUsage::DEFAULT); - mStarburstTexture = driver.createTexture(SamplerType::SAMPLER_2D, 1, TextureFormat::R8, 1, 256, 1, 1, TextureUsage::DEFAULT); @@ -277,17 +268,26 @@ void PostProcessManager::init() noexcept { float r = 0.5f + 0.5f * dist(gen); return uint8_t(r * 255.0f); }); - driver.update2DImage(mDummyOneTexture, 0, 0, 0, 1, 1, std::move(dataOne)); - driver.update3DImage(mDummyOneTextureArray, 0, 0, 0, 0, 1, 1, 1, std::move(dataOneArray)); - driver.update2DImage(mDummyZeroTexture, 0, 0, 0, 1, 1, std::move(dataZero)); - driver.update2DImage(mStarburstTexture, 0, 0, 0, 256, 1, std::move(dataStarburst)); + + driver.update2DImage(engine.getOneTexture(), + 0, 0, 0, 1, 1, + std::move(dataOne)); + + driver.update3DImage(engine.getOneTextureArray(), + 0, 0, 0, 0, 1, 1, 1, + std::move(dataOneArray)); + + driver.update2DImage(engine.getZeroTexture(), + 0, 0, 0, 1, 1, + std::move(dataZero)); + + driver.update2DImage(mStarburstTexture, + 0, 0, 0, 256, 1, + std::move(dataStarburst)); } void PostProcessManager::terminate(DriverApi& driver) noexcept { FEngine& engine = mEngine; - driver.destroyTexture(mDummyOneTexture); - driver.destroyTexture(mDummyOneTextureArray); - driver.destroyTexture(mDummyZeroTexture); driver.destroyTexture(mStarburstTexture); auto first = mMaterialRegistry.begin(); auto last = mMaterialRegistry.end(); @@ -297,6 +297,18 @@ void PostProcessManager::terminate(DriverApi& driver) noexcept { } } +backend::Handle PostProcessManager::getOneTexture() const { + return mEngine.getOneTexture(); +} + +backend::Handle PostProcessManager::getZeroTexture() const { + return mEngine.getZeroTexture(); +} + +backend::Handle PostProcessManager::getOneTextureArray() const { + return mEngine.getOneTextureArray(); +} + UTILS_NOINLINE void PostProcessManager::commitAndRender(FrameGraphResources::RenderPassInfo const& out, PostProcessMaterial const& material, uint8_t variant, DriverApi& driver) const noexcept { diff --git a/filament/src/PostProcessManager.h b/filament/src/PostProcessManager.h index 6092571eca..55bec55cb6 100644 --- a/filament/src/PostProcessManager.h +++ b/filament/src/PostProcessManager.h @@ -156,9 +156,9 @@ public: FrameGraphId output, uint8_t dstLevel, uint8_t layer, bool reinhard, size_t kernelWidth, float sigma = 6.0f) noexcept; - backend::Handle getOneTexture() const { return mDummyOneTexture; } - backend::Handle getZeroTexture() const { return mDummyZeroTexture; } - backend::Handle getOneTextureArray() const { return mDummyOneTextureArray; } + backend::Handle getOneTexture() const; + backend::Handle getZeroTexture() const; + backend::Handle getOneTextureArray() const; math::float2 halton(size_t index) const noexcept { return mHaltonSamples[index & 0xFu]; @@ -234,9 +234,6 @@ private: void registerPostProcessMaterial(utils::StaticString name, uint8_t const* data, int size); PostProcessMaterial& getPostProcessMaterial(utils::StaticString name) noexcept; - backend::Handle mDummyOneTexture; - backend::Handle mDummyOneTextureArray; - backend::Handle mDummyZeroTexture; backend::Handle mStarburstTexture; std::uniform_real_distribution mUniformDistribution{0.0f, 1.0f}; diff --git a/filament/src/RenderPass.cpp b/filament/src/RenderPass.cpp index e1ce03ed80..b30dd5dab6 100644 --- a/filament/src/RenderPass.cpp +++ b/filament/src/RenderPass.cpp @@ -528,12 +528,13 @@ void RenderPass::Executor::execute(const char* name, engine.flush(); driver.beginRenderPass(renderTarget, params); - recordDriverCommands(driver, mBegin, mEnd, mRenderableSoa); + recordDriverCommands(engine, driver, mBegin, mEnd, mRenderableSoa); driver.endRenderPass(); } UTILS_NOINLINE // no need to be inlined -void RenderPass::Executor::recordDriverCommands(backend::DriverApi& driver, +void RenderPass::Executor::recordDriverCommands(FEngine& engine, + backend::DriverApi& driver, const Command* first, const Command* last, FScene::RenderableSoa const& soa) const noexcept { SYSTRACE_CALL(); @@ -589,6 +590,11 @@ void RenderPass::Executor::recordDriverCommands(backend::DriverApi& driver, skinning.handle, skinning.offset * sizeof(PerRenderableUibBone), CONFIG_MAX_BONE_COUNT * sizeof(PerRenderableUibBone)); + + if (!info.morphTargetBuffer) { + driver.bindSamplers(BindingPoints::PER_RENDERABLE_MORPHING, + engine.getDummyMorphingSamplerGroup()); + } } if (UTILS_UNLIKELY(info.morphWeightBuffer)) { @@ -598,7 +604,7 @@ void RenderPass::Executor::recordDriverCommands(backend::DriverApi& driver, info.morphWeightBuffer); // When only skinning is enabled, morphTargetBuffer isn't created. - if (UTILS_UNLIKELY(info.morphTargetBuffer)) { + if (info.morphTargetBuffer) { driver.bindSamplers(BindingPoints::PER_RENDERABLE_MORPHING, info.morphTargetBuffer); } diff --git a/filament/src/RenderPass.h b/filament/src/RenderPass.h index d4fc548f85..53962ddcd3 100644 --- a/filament/src/RenderPass.h +++ b/filament/src/RenderPass.h @@ -333,7 +333,7 @@ public: assert_invariant(e <= pass->end()); } - void recordDriverCommands(backend::DriverApi& driver, + void recordDriverCommands(FEngine& engine, backend::DriverApi& driver, const Command* first, const Command* last, FScene::RenderableSoa const& soa) const noexcept; diff --git a/filament/src/details/Engine.h b/filament/src/details/Engine.h index 9f6e1e1b0e..ee3e846e7f 100644 --- a/filament/src/details/Engine.h +++ b/filament/src/details/Engine.h @@ -332,10 +332,15 @@ public: return mRandomEngine; } - void pumpMessageQueues() { + void pumpMessageQueues() const { getDriver().purge(); } + backend::Handle getOneTexture() const { return mDummyOneTexture; } + backend::Handle getZeroTexture() const { return mDummyZeroTexture; } + backend::Handle getOneTextureArray() const { return mDummyOneTextureArray; } + backend::Handle getDummyMorphingSamplerGroup() const { return mDummyMorphingSamplerGroup; } + private: FEngine(Backend backend, Platform* platform, void* sharedGLContext); void init(); @@ -424,6 +429,11 @@ private: mutable filaflat::ShaderBuilder mFragmentShaderBuilder; FDebugRegistry mDebugRegistry; + backend::Handle mDummyOneTexture; + backend::Handle mDummyOneTextureArray; + backend::Handle mDummyZeroTexture; + backend::Handle mDummyMorphingSamplerGroup; + std::thread::id mMainThreadId{}; public: diff --git a/filament/src/details/MorphTargetBuffer.h b/filament/src/details/MorphTargetBuffer.h index c219456f52..314ac3aebd 100644 --- a/filament/src/details/MorphTargetBuffer.h +++ b/filament/src/details/MorphTargetBuffer.h @@ -48,6 +48,8 @@ public: inline size_t getVertexCount() const noexcept { return mVertexCount; } inline size_t getCount() const noexcept { return mCount; } + static backend::Handle createDummySampleGroup(FEngine& engine) noexcept; + private: friend class FView; friend class RenderPass;