From d92a2292e61d1123ea277776c4c533b392c31d1a Mon Sep 17 00:00:00 2001 From: Powei Feng Date: Wed, 18 Dec 2024 14:12:05 -0800 Subject: [PATCH] matdbg: Fix material collision 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 5f641eb167f2..f1bdaf2742b2 100644 --- a/filament/src/details/Material.cpp +++ b/filament/src/details/Material.cpp @@ -605,13 +605,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]; @@ -630,7 +627,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 eb578be3a3a7..5dd55e733ec8 100644 --- a/filament/src/details/Material.h +++ b/filament/src/details/Material.h @@ -156,6 +156,13 @@ class FMaterial : public Material { 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 @@ class FMaterial : public Material { 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 2416931e6656..288d32260234 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 4a7c7df4e444..cccec2b1b67b 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,