From 94b8ee481ff868636de9ffebcc9af20f83fa89a8 Mon Sep 17 00:00:00 2001 From: Ben Doherty Date: Mon, 11 Aug 2025 17:30:07 -0400 Subject: [PATCH] Fix: webgpu error regarding mismatched pipeline (#9056) --- filament/src/RenderPass.cpp | 3 ++- filament/src/details/Engine.cpp | 3 +++ filament/src/details/Material.h | 14 ++++++++++++-- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/filament/src/RenderPass.cpp b/filament/src/RenderPass.cpp index 26ebc37121..2d005f2dd1 100644 --- a/filament/src/RenderPass.cpp +++ b/filament/src/RenderPass.cpp @@ -1067,7 +1067,8 @@ void RenderPass::Executor::execute(FEngine const& engine, DriverApi& driver, // Each material has a per-material descriptor-set layout which encodes the // material's parameters (ubo and samplers) pipeline.pipelineLayout.setLayout[+DescriptorSetBindingPoints::PER_MATERIAL] = - ma->getDescriptorSetLayout().getHandle(); + ma->getDescriptorSetLayout(info.materialVariant).getHandle(); + if (UTILS_UNLIKELY(ma->getMaterialDomain() == MaterialDomain::POST_PROCESS)) { // It is possible to get a post-process material here (even though it's diff --git a/filament/src/details/Engine.cpp b/filament/src/details/Engine.cpp index 58fc61a6d0..f4d217cb04 100644 --- a/filament/src/details/Engine.cpp +++ b/filament/src/details/Engine.cpp @@ -465,6 +465,9 @@ void FEngine::init() { } mDefaultMaterial = downcast(defaultMaterialBuilder.build(*this)); } + // We must commit the default material instance here. It may not be used in a scene, but its + // descriptor set may still be used for shared variants. + mDefaultMaterial->getDefaultInstance()->commit(driverApi); if (UTILS_UNLIKELY(getSupportedFeatureLevel() >= FeatureLevel::FEATURE_LEVEL_1)) { mDefaultColorGrading = downcast(ColorGrading::Builder().build(*this)); diff --git a/filament/src/details/Material.h b/filament/src/details/Material.h index 850a3d8ec8..a7eb90e65e 100644 --- a/filament/src/details/Material.h +++ b/filament/src/details/Material.h @@ -96,8 +96,18 @@ public: DescriptorSetLayout const& getPerViewDescriptorSetLayout( Variant const variant, bool const useVsmDescriptorSetLayout) const noexcept; - DescriptorSetLayout const& getDescriptorSetLayout() const noexcept { - return mDescriptorSetLayout; + // Returns the layout that should be used when this material is bound to the pipeline for the + // given variant. Shared variants use the Engine's default material's variants, so we should + // also use the default material's layout. + DescriptorSetLayout const& getDescriptorSetLayout(Variant variant = {}) const noexcept { + if (!isSharedVariant(variant)) { + return mDescriptorSetLayout; + } + FMaterial const* const pDefaultMaterial = mEngine.getDefaultMaterial(); + if (UTILS_UNLIKELY(!pDefaultMaterial)) { + return mDescriptorSetLayout; + } + return pDefaultMaterial->getDescriptorSetLayout(); } void compile(CompilerPriorityQueue priority,