From aa09d86b5a3788c62ec389941102b1770dfbd983 Mon Sep 17 00:00:00 2001 From: Powei Feng Date: Thu, 19 Dec 2024 12:14:08 -0800 Subject: [PATCH] matdbg: Fix material collision (#8322) Fix 3 bugs wrt matdbg: 1. The numbering scheme for materials with same name was buggy 2. The shared depth variants of the default material should also show up as active material variants. 3. When two instantiation of FMaterial point to the exact same bits, we still need to treat them as two materials. (Otherwise we wouldn't be able to modify one of them in matdbg). --- filament/src/details/Material.cpp | 9 +++------ filament/src/details/Material.h | 12 ++++++++++++ libs/matdbg/src/DebugServer.cpp | 8 ++++++-- libs/matdbg/web/app.js | 2 +- 4 files changed, 22 insertions(+), 9 deletions(-) diff --git a/filament/src/details/Material.cpp b/filament/src/details/Material.cpp index 651b88cf02..be8ca04be2 100644 --- a/filament/src/details/Material.cpp +++ b/filament/src/details/Material.cpp @@ -611,13 +611,10 @@ void FMaterial::createAndCacheProgram(Program&& p, Variant variant) const noexce FEngine const& engine = mEngine; DriverApi& driverApi = mEngine.getDriverApi(); - bool const isSharedVariant = - (mMaterialDomain == MaterialDomain::SURFACE) && - !mIsDefaultMaterial && !mHasCustomDepthShader && - Variant::isValidDepthVariant(variant); + bool const isShared = isSharedVariant(variant); // Check if the default material has this program cached - if (isSharedVariant) { + if (isShared) { FMaterial const* const pDefaultMaterial = engine.getDefaultMaterial(); if (pDefaultMaterial) { auto program = pDefaultMaterial->mCachedPrograms[variant.key]; @@ -636,7 +633,7 @@ void FMaterial::createAndCacheProgram(Program&& p, Variant variant) const noexce // If the default material doesn't already have this program cached, and all caching conditions // are met (Surface Domain and no custom depth shader), cache it now. // New Materials will inherit these program automatically. - if (isSharedVariant) { + if (isShared) { FMaterial const* const pDefaultMaterial = engine.getDefaultMaterial(); if (pDefaultMaterial && !pDefaultMaterial->mCachedPrograms[variant.key]) { // set the tag to the default material name diff --git a/filament/src/details/Material.h b/filament/src/details/Material.h index eb578be3a3..5dd55e733e 100644 --- a/filament/src/details/Material.h +++ b/filament/src/details/Material.h @@ -156,6 +156,13 @@ public: std::unique_lock lock(mActiveProgramsLock); mActivePrograms.set(variant.key); lock.unlock(); + + if (isSharedVariant(variant)) { + FMaterial const* const pDefaultMaterial = mEngine.getDefaultMaterial(); + if (pDefaultMaterial && pDefaultMaterial->mCachedPrograms[variant.key]) { + return pDefaultMaterial->getProgram(variant); + } + } #endif assert_invariant(mCachedPrograms[variant.key]); return mCachedPrograms[variant.key]; @@ -290,6 +297,11 @@ private: void createAndCacheProgram(backend::Program&& p, Variant variant) const noexcept; + inline bool isSharedVariant(Variant variant) const { + return (mMaterialDomain == MaterialDomain::SURFACE) && !mIsDefaultMaterial && + !mHasCustomDepthShader && Variant::isValidDepthVariant(variant); + } + // try to order by frequency of use mutable std::array, VARIANT_COUNT> mCachedPrograms; DescriptorSetLayout mPerViewDescriptorSetLayout; diff --git a/libs/matdbg/src/DebugServer.cpp b/libs/matdbg/src/DebugServer.cpp index 96c9538620..803cf00fba 100644 --- a/libs/matdbg/src/DebugServer.cpp +++ b/libs/matdbg/src/DebugServer.cpp @@ -193,8 +193,12 @@ DebugServer::addMaterial(const CString& name, const void* data, size_t size, voi return {}; } - const uint32_t seed = 42; - const MaterialKey key = utils::hash::murmurSlow((const uint8_t*) data, size, seed); + // Note that it's possible to have two materials with the exact same content (however wasteful), + // but they refer to different instantiation of FMaterial. Hence we hash on userdata and the + // material data. + constexpr uint32_t seed = 42; + uint64_t dataSpace[2] = {(uint64_t) data, (uint64_t) userdata}; + uint32_t const key = utils::hash::murmur3((const uint32_t*) dataSpace, sizeof(dataSpace), seed); // Retain a copy of the package to permit queries after the client application has // freed up the original material package. diff --git a/libs/matdbg/web/app.js b/libs/matdbg/web/app.js index 4a7c7df4e4..cccec2b1b6 100644 --- a/libs/matdbg/web/app.js +++ b/libs/matdbg/web/app.js @@ -662,8 +662,8 @@ class MaterialSidePanel extends LitElement { let name = material.name || kUntitledPlaceholder; if (name in duplicatedLabels) { const index = duplicatedLabels[name]; - name = `${name} (${index})`; duplicatedLabels[name] = index + 1; + name = `${name} (${index})`; } return { matid: matid,