From 3e1ea7cdfd79aec636376ab3705cbcf53bd4d36c Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Fri, 2 May 2025 16:08:21 -0700 Subject: [PATCH] clean-up our handling of descriptor-sets a bit more the main aim of this PR is to consolidate how we access the "per view" descriptor set to a single place. some validation code is moved into DescriptorSets.cpp, so we get a more centralized idea of what we do with the descriptors. also factorize in one place the filtering of sampler list by layouts. --- .../include/private/filament/DescriptorSets.h | 11 +- .../private/filament/SamplerInterfaceBlock.h | 5 + libs/filabridge/src/DescriptorSets.cpp | 118 ++++++++++++++---- libs/filabridge/src/SamplerInterfaceBlock.cpp | 23 +++- libs/filamat/src/GLSLPostProcessor.cpp | 93 +++++++------- libs/filamat/src/MaterialVariants.cpp | 64 +--------- libs/filamat/src/SamplerBindingMap.cpp | 0 libs/filamat/src/SamplerBindingMap.h | 0 libs/filamat/src/shaders/ShaderGenerator.cpp | 44 +------ libs/filamat/src/shaders/ShaderGenerator.h | 7 -- 10 files changed, 180 insertions(+), 185 deletions(-) delete mode 100644 libs/filamat/src/SamplerBindingMap.cpp delete mode 100644 libs/filamat/src/SamplerBindingMap.h diff --git a/libs/filabridge/include/private/filament/DescriptorSets.h b/libs/filabridge/include/private/filament/DescriptorSets.h index 171c8650d1..5ee10729b4 100644 --- a/libs/filabridge/include/private/filament/DescriptorSets.h +++ b/libs/filabridge/include/private/filament/DescriptorSets.h @@ -20,6 +20,7 @@ #include #include +#include #include @@ -39,8 +40,16 @@ backend::DescriptorSetLayout getPerViewDescriptorSetLayout( ReflectionMode reflectionMode, RefractionMode refractionMode) noexcept; +backend::DescriptorSetLayout getPerViewDescriptorSetLayoutWithVariant( + Variant variant, + MaterialDomain domain, + UserVariantFilterMask variantFilter, + bool isLit, + ReflectionMode reflectionMode, + RefractionMode refractionMode) noexcept; + utils::CString getDescriptorName( - filament::DescriptorSetBindingPoints set, + DescriptorSetBindingPoints set, backend::descriptor_binding_t binding) noexcept; } // namespace filament::descriptor_sets diff --git a/libs/filabridge/include/private/filament/SamplerInterfaceBlock.h b/libs/filabridge/include/private/filament/SamplerInterfaceBlock.h index 243f2dcfb6..28e5e8d4eb 100644 --- a/libs/filabridge/include/private/filament/SamplerInterfaceBlock.h +++ b/libs/filabridge/include/private/filament/SamplerInterfaceBlock.h @@ -23,6 +23,8 @@ #include #include +#include + #include #include #include @@ -128,6 +130,9 @@ public: static utils::CString generateUniformName(const char* group, const char* sampler) noexcept; + static SamplerInfoList filterSamplerList(SamplerInfoList list, + backend::DescriptorSetLayout const& descriptorSetLayout); + private: friend class Builder; diff --git a/libs/filabridge/src/DescriptorSets.cpp b/libs/filabridge/src/DescriptorSets.cpp index b313fcc056..cdcd44b9d0 100644 --- a/libs/filabridge/src/DescriptorSets.cpp +++ b/libs/filabridge/src/DescriptorSets.cpp @@ -17,6 +17,7 @@ #include "private/filament/DescriptorSets.h" #include +#include #include @@ -26,34 +27,35 @@ #include #include -#include +#include #include +#include namespace filament::descriptor_sets { using namespace backend; -static DescriptorSetLayout const postProcessDescriptorSetLayout{{ +static constexpr std::initializer_list postProcessDescriptorSetLayoutList = { { DescriptorType::UNIFORM_BUFFER, ShaderStageFlags::VERTEX | ShaderStageFlags::FRAGMENT, +PerViewBindingPoints::FRAME_UNIFORMS }, -}}; +}; -static DescriptorSetLayout const depthVariantDescriptorSetLayout{{ +static constexpr std::initializer_list depthVariantDescriptorSetLayoutList = { { DescriptorType::UNIFORM_BUFFER, ShaderStageFlags::VERTEX | ShaderStageFlags::FRAGMENT, +PerViewBindingPoints::FRAME_UNIFORMS }, -}}; +}; // ssrVariantDescriptorSetLayout must match perViewDescriptorSetLayout's vertex stage. This is // because the SSR variant is always using the "standard" vertex shader (i.e. there is no // dedicated SSR vertex shader), which uses perViewDescriptorSetLayout. // This means that PerViewBindingPoints::SHADOWS must be in the layout even though it's not used // by the SSR variant. -static DescriptorSetLayout const ssrVariantDescriptorSetLayout{{ - { DescriptorType::UNIFORM_BUFFER, ShaderStageFlags::VERTEX | ShaderStageFlags::FRAGMENT, +PerViewBindingPoints::FRAME_UNIFORMS }, - { DescriptorType::UNIFORM_BUFFER, ShaderStageFlags::VERTEX | ShaderStageFlags::FRAGMENT, +PerViewBindingPoints::SHADOWS }, - { DescriptorType::SAMPLER, ShaderStageFlags::FRAGMENT, +PerViewBindingPoints::STRUCTURE }, - { DescriptorType::SAMPLER, ShaderStageFlags::FRAGMENT, +PerViewBindingPoints::SSR }, -}}; +static constexpr std::initializer_list ssrVariantDescriptorSetLayoutList = { + { DescriptorType::UNIFORM_BUFFER, ShaderStageFlags::VERTEX | ShaderStageFlags::FRAGMENT, +PerViewBindingPoints::FRAME_UNIFORMS }, + { DescriptorType::UNIFORM_BUFFER, ShaderStageFlags::VERTEX | ShaderStageFlags::FRAGMENT, +PerViewBindingPoints::SHADOWS }, + { DescriptorType::SAMPLER, ShaderStageFlags::FRAGMENT, +PerViewBindingPoints::STRUCTURE }, + { DescriptorType::SAMPLER, ShaderStageFlags::FRAGMENT, +PerViewBindingPoints::SSR }, +}; -static DescriptorSetLayout perViewDescriptorSetLayout = {{ +static constexpr std::initializer_list perViewDescriptorSetLayoutList = { { DescriptorType::UNIFORM_BUFFER, ShaderStageFlags::VERTEX | ShaderStageFlags::FRAGMENT, +PerViewBindingPoints::FRAME_UNIFORMS }, { DescriptorType::UNIFORM_BUFFER, ShaderStageFlags::VERTEX | ShaderStageFlags::FRAGMENT, +PerViewBindingPoints::SHADOWS }, { DescriptorType::UNIFORM_BUFFER, ShaderStageFlags::FRAGMENT, +PerViewBindingPoints::LIGHTS }, @@ -66,16 +68,30 @@ static DescriptorSetLayout perViewDescriptorSetLayout = {{ { DescriptorType::SAMPLER, ShaderStageFlags::FRAGMENT, +PerViewBindingPoints::SSAO }, { DescriptorType::SAMPLER, ShaderStageFlags::FRAGMENT, +PerViewBindingPoints::SSR }, { DescriptorType::SAMPLER, ShaderStageFlags::FRAGMENT, +PerViewBindingPoints::FOG }, -}}; +}; -static DescriptorSetLayout perRenderableDescriptorSetLayout = {{ +static constexpr std::initializer_list perRenderableDescriptorSetLayoutList = { { DescriptorType::UNIFORM_BUFFER, ShaderStageFlags::VERTEX | ShaderStageFlags::FRAGMENT, +PerRenderableBindingPoints::OBJECT_UNIFORMS, DescriptorFlags::DYNAMIC_OFFSET }, { DescriptorType::UNIFORM_BUFFER, ShaderStageFlags::VERTEX | ShaderStageFlags::FRAGMENT, +PerRenderableBindingPoints::BONES_UNIFORMS, DescriptorFlags::DYNAMIC_OFFSET }, { DescriptorType::UNIFORM_BUFFER, ShaderStageFlags::VERTEX | ShaderStageFlags::FRAGMENT, +PerRenderableBindingPoints::MORPHING_UNIFORMS }, { DescriptorType::SAMPLER, ShaderStageFlags::VERTEX , +PerRenderableBindingPoints::MORPH_TARGET_POSITIONS }, { DescriptorType::SAMPLER, ShaderStageFlags::VERTEX , +PerRenderableBindingPoints::MORPH_TARGET_TANGENTS }, { DescriptorType::SAMPLER, ShaderStageFlags::VERTEX , +PerRenderableBindingPoints::BONES_INDICES_AND_WEIGHTS }, -}}; +}; + +// used for post-processing passes +static DescriptorSetLayout const postProcessDescriptorSetLayout{ postProcessDescriptorSetLayoutList }; + +// used to generate shadow-maps +static DescriptorSetLayout const depthVariantDescriptorSetLayout{ depthVariantDescriptorSetLayoutList }; + +static DescriptorSetLayout const ssrVariantDescriptorSetLayout{ ssrVariantDescriptorSetLayoutList }; + +// Used for generating the color pass (i.e. the main pass). This is in fact a template that gets +// declined into 8 different layouts, based on variants. +static DescriptorSetLayout perViewDescriptorSetLayout = { perViewDescriptorSetLayoutList }; + +static DescriptorSetLayout perRenderableDescriptorSetLayout = { perRenderableDescriptorSetLayoutList }; DescriptorSetLayout const& getPostProcessLayout() noexcept { return postProcessDescriptorSetLayout; @@ -93,8 +109,8 @@ DescriptorSetLayout const& getPerRenderableLayout() noexcept { return perRenderableDescriptorSetLayout; } -utils::CString getDescriptorName(DescriptorSetBindingPoints set, - descriptor_binding_t binding) noexcept { +utils::CString getDescriptorName(DescriptorSetBindingPoints const set, + descriptor_binding_t const binding) noexcept { using namespace std::literals; static std::unordered_map const set0{{ @@ -140,11 +156,11 @@ utils::CString getDescriptorName(DescriptorSetBindingPoints set, } DescriptorSetLayout getPerViewDescriptorSetLayout( - MaterialDomain domain, - UserVariantFilterMask variantFilter, - bool isLit, - ReflectionMode reflectionMode, - RefractionMode refractionMode) noexcept { + MaterialDomain const domain, + UserVariantFilterMask const variantFilter, + bool const isLit, + ReflectionMode const reflectionMode, + RefractionMode const refractionMode) noexcept { bool const ssr = reflectionMode == ReflectionMode::SCREEN_SPACE || refractionMode == RefractionMode::SCREEN_SPACE; @@ -187,11 +203,65 @@ DescriptorSetLayout getPerViewDescriptorSetLayout( return layout; } case MaterialDomain::POST_PROCESS: - return descriptor_sets::getPostProcessLayout(); + return postProcessDescriptorSetLayout; case MaterialDomain::COMPUTE: // TODO: what's the layout for compute? - return descriptor_sets::getPostProcessLayout(); + return postProcessDescriptorSetLayout; } } +DescriptorSetLayout getPerViewDescriptorSetLayoutWithVariant( + Variant const variant, + MaterialDomain domain, + UserVariantFilterMask const variantFilter, + bool const isLit, + ReflectionMode const reflectionMode, + RefractionMode const refractionMode) noexcept { + if (Variant::isValidDepthVariant(variant)) { + return depthVariantDescriptorSetLayout; + } + if (Variant::isSSRVariant(variant)) { + return ssrVariantDescriptorSetLayout; + } + // We need to filter out all the descriptors not included in the "resolved" layout below + return getPerViewDescriptorSetLayout(domain, variantFilter, + isLit, reflectionMode, refractionMode); +} + + + +template +constexpr static ITERATOR find_if(ITERATOR first, ITERATOR last, PREDICATE pred) { + for (; first != last; ++first) + if (pred(*first)) break; + return first; +} + +constexpr static bool checkConsistency() noexcept { + // check that all descriptors that apply to the vertex stage in perViewDescriptorSetLayout + // are present in ssrVariantDescriptorSetLayout; meaning that the latter is compatible + // with the former. + for (auto const& r: perViewDescriptorSetLayoutList) { + if (hasShaderType(r.stageFlags, ShaderStage::VERTEX)) { + auto const pos = find_if( + ssrVariantDescriptorSetLayoutList.begin(), + ssrVariantDescriptorSetLayoutList.end(), + [r](auto const& l) { + return l.count == r.count && + l.type == r.type && + l.binding == r.binding && + l.flags == r.flags && + l.stageFlags == r.stageFlags; + }); + if (pos == ssrVariantDescriptorSetLayoutList.end()) { + return false; + } + } + } + return true; +} + +static_assert(checkConsistency(), "ssrVariantDescriptorSetLayout is not compatible with " + "perViewDescriptorSetLayout"); + } // namespace filament::descriptor_sets diff --git a/libs/filabridge/src/SamplerInterfaceBlock.cpp b/libs/filabridge/src/SamplerInterfaceBlock.cpp index 1d1f4c387f..da2a1a76c4 100644 --- a/libs/filabridge/src/SamplerInterfaceBlock.cpp +++ b/libs/filabridge/src/SamplerInterfaceBlock.cpp @@ -16,6 +16,7 @@ #include "private/filament/SamplerInterfaceBlock.h" +#include #include @@ -102,7 +103,7 @@ const SamplerInterfaceBlock::SamplerInfo* SamplerInterfaceBlock::getSamplerInfo( return &mSamplersInfoList[pos->second]; } -utils::CString SamplerInterfaceBlock::generateUniformName(const char* group, const char* sampler) noexcept { +CString SamplerInterfaceBlock::generateUniformName(const char* group, const char* sampler) noexcept { char uniformName[256]; // sampler interface block name @@ -117,9 +118,27 @@ utils::CString SamplerInterfaceBlock::generateUniformName(const char* group, con std::min(sizeof(uniformName) / 2 - 2, strlen(sampler)), prefix + 1); *last++ = 0; // null terminator - assert(last <= std::end(uniformName)); + assert_invariant(last <= std::end(uniformName)); return CString{ uniformName, size_t(last - uniformName) - 1u }; } +SamplerInterfaceBlock::SamplerInfoList SamplerInterfaceBlock::filterSamplerList( + SamplerInfoList list, backend::DescriptorSetLayout const& descriptorSetLayout) { + // remove all the samplers that are not included in the descriptor-set layout + list.erase( + std::remove_if(list.begin(), list.end(), + [&](auto const& entry) { + auto pos = std::find_if( + descriptorSetLayout.bindings.begin(), + descriptorSetLayout.bindings.end(), + [&entry](const auto& item) { + return item.binding == entry.binding; + }); + return pos == descriptorSetLayout.bindings.end(); + }), list.end()); + + return list; +} + } // namespace filament diff --git a/libs/filamat/src/GLSLPostProcessor.cpp b/libs/filamat/src/GLSLPostProcessor.cpp index 3283f2bd3f..52d4a30dc0 100644 --- a/libs/filamat/src/GLSLPostProcessor.cpp +++ b/libs/filamat/src/GLSLPostProcessor.cpp @@ -34,14 +34,19 @@ #include "MetalArgumentBuffer.h" #include "SpirvFixup.h" -#include "utils/ostream.h" #include +#include +#include #include +#include +#include +#include #include #include +#include #include #ifdef FILAMENT_SUPPORTS_WEBGPU @@ -151,21 +156,16 @@ DescriptorSetLayout getPerMaterialDescriptorSet(SamplerInterfaceBlock const& sib return layout; } -static void collectDescriptorsForSet(filament::DescriptorSetBindingPoints set, +static void collectDescriptorsForSet(DescriptorSetBindingPoints set, const GLSLPostProcessor::Config& config, DescriptorSetInfo& descriptors) { const MaterialInfo& material = *config.materialInfo; - DescriptorSetLayout const info = [&]() { + // get the descriptor set layout for the given pinding point + DescriptorSetLayout const descriptorSetLayout = [&] { switch (set) { case DescriptorSetBindingPoints::PER_VIEW: { - if (filament::Variant::isValidDepthVariant(config.variant)) { - return descriptor_sets::getDepthVariantLayout(); - } - if (filament::Variant::isSSRVariant(config.variant)) { - return descriptor_sets::getSsrVariantLayout(); - } - return descriptor_sets::getPerViewDescriptorSetLayout(config.domain, - config.variantFilter, + return descriptor_sets::getPerViewDescriptorSetLayoutWithVariant( + config.variant, config.domain, config.variantFilter, material.isLit || material.hasShadowMultiplier, material.reflectionMode, material.refractionMode); @@ -179,7 +179,8 @@ static void collectDescriptorsForSet(filament::DescriptorSetBindingPoints set, } }(); - auto samplerList = [&]() { + // get the sampler list for this binding point + auto samplerList = [&] { switch (set) { case DescriptorSetBindingPoints::PER_VIEW: return SibGenerator::getPerViewSib(config.variant).getSamplerInfoList(); @@ -192,42 +193,34 @@ static void collectDescriptorsForSet(filament::DescriptorSetBindingPoints set, } }(); - // remove all the samplers that are not included in the descriptor-set layout - samplerList.erase(std::remove_if(samplerList.begin(), samplerList.end(), - [&info](auto const& entry) { - auto pos = std::find_if(info.bindings.begin(), - info.bindings.end(), [&entry](const auto& item) { - return item.binding == entry.binding; - }); - return pos == info.bindings.end(); - }), - samplerList.end()); + // filter the list with the descriptor set layout + auto const descriptorSetSamplerList = + SamplerInterfaceBlock::filterSamplerList(std::move(samplerList), descriptorSetLayout); - auto getDescriptorName = [&](DescriptorSetBindingPoints set, descriptor_binding_t binding) { + // helper to get the name of a descriptor for this set, given a binding. + auto getDescriptorName = [set, &descriptorSetSamplerList](descriptor_binding_t binding) { if (set == DescriptorSetBindingPoints::PER_MATERIAL) { - auto pos = std::find_if(samplerList.begin(), samplerList.end(), + auto pos = std::find_if(descriptorSetSamplerList.begin(), descriptorSetSamplerList.end(), [&](const auto& entry) { return entry.binding == binding; }); - if (pos == samplerList.end()) { + if (pos == descriptorSetSamplerList.end()) { return descriptor_sets::getDescriptorName(set, binding); } - SamplerInterfaceBlock::SamplerInfo& sampler = *pos; - return sampler.uniformName; + return pos->uniformName; } return descriptor_sets::getDescriptorName(set, binding); }; - for (size_t i = 0; i < info.bindings.size(); i++) { - backend::descriptor_binding_t binding = info.bindings[i].binding; - auto name = getDescriptorName(set, binding); - if (info.bindings[i].type == DescriptorType::SAMPLER || - info.bindings[i].type == DescriptorType::SAMPLER_EXTERNAL) { - auto pos = std::find_if(samplerList.begin(), samplerList.end(), + for (auto descriptor : descriptorSetLayout.bindings) { + descriptor_binding_t binding = descriptor.binding; + auto name = getDescriptorName(binding); + if (descriptor.type == DescriptorType::SAMPLER || + descriptor.type == DescriptorType::SAMPLER_EXTERNAL) { + auto pos = std::find_if(descriptorSetSamplerList.begin(), descriptorSetSamplerList.end(), [&](const auto& entry) { return entry.binding == binding; }); - assert_invariant(pos != samplerList.end()); - SamplerInterfaceBlock::SamplerInfo& sampler = *pos; - descriptors.emplace_back(name, info.bindings[i], sampler); + assert_invariant(pos != descriptorSetSamplerList.end()); + descriptors.emplace_back(name, descriptor, *pos); } else { - descriptors.emplace_back(name, info.bindings[i], std::nullopt); + descriptors.emplace_back(name, descriptor, std::nullopt); } } @@ -365,7 +358,7 @@ static std::string stringifySpvOptimizerMessage(spv_message_level_t level, const } void GLSLPostProcessor::spirvToMsl(const SpirvBlob* spirv, std::string* outMsl, - filament::backend::ShaderStage stage, filament::backend::ShaderModel shaderModel, + ShaderStage stage, ShaderModel shaderModel, bool useFramebufferFetch, const DescriptorSets& descriptorSets, const ShaderMinifier* minifier) { using namespace msl; @@ -674,7 +667,7 @@ bool GLSLPostProcessor::process(const std::string& inputShader, Config const& co // SpvRules should be enough. // I think this could cause the compilation to fail on gl_VertexID. using Type = std::underlying_type_t; - msg = EShMessages(Type(msg) | Type(EShMessages::EShMsgVulkanRules)); + msg = EShMessages(Type(msg) | Type(EShMsgVulkanRules)); } bool const ok = tShader.parse(&DefaultTBuiltInResource, internalConfig.langVersion, false, msg); @@ -684,7 +677,7 @@ bool GLSLPostProcessor::process(const std::string& inputShader, Config const& co } // add texture lod bias - if (config.shaderType == backend::ShaderStage::FRAGMENT && + if (config.shaderType == ShaderStage::FRAGMENT && config.domain == MaterialDomain::SURFACE) { GLSLTools::textureLodBias(tShader); } @@ -760,8 +753,8 @@ bool GLSLPostProcessor::process(const std::string& inputShader, Config const& co return true; } -bool GLSLPostProcessor::preprocessOptimization(glslang::TShader& tShader, - GLSLPostProcessor::Config const& config, InternalConfig& internalConfig) const { +bool GLSLPostProcessor::preprocessOptimization(TShader& tShader, + Config const& config, InternalConfig& internalConfig) const { using TargetApi = MaterialBuilder::TargetApi; assert_invariant(bool(internalConfig.spirvOutput) == (config.targetApi != TargetApi::OPENGL)); @@ -832,7 +825,7 @@ bool GLSLPostProcessor::preprocessOptimization(glslang::TShader& tShader, } bool GLSLPostProcessor::fullOptimization(const TShader& tShader, - GLSLPostProcessor::Config const& config, InternalConfig& internalConfig) const { + Config const& config, InternalConfig& internalConfig) const { SpirvBlob spirv; bool const optimizeForSize = mOptimization == MaterialBuilderBase::Optimization::SIZE; @@ -928,7 +921,7 @@ bool GLSLPostProcessor::fullOptimization(const TShader& tShader, #else try { *internalConfig.glslOutput = glslCompiler.compile(); - } catch (spirv_cross::CompilerError e) { + } catch (CompilerError e) { slog.e << "ERROR: " << e.what() << io::endl; return false; } @@ -948,8 +941,8 @@ bool GLSLPostProcessor::fullOptimization(const TShader& tShader, return true; } -std::shared_ptr GLSLPostProcessor::createEmptyOptimizer() { - auto optimizer = std::make_shared(SPV_ENV_UNIVERSAL_1_3); +std::shared_ptr GLSLPostProcessor::createEmptyOptimizer() { + auto optimizer = std::make_shared(SPV_ENV_UNIVERSAL_1_3); optimizer->SetMessageConsumer([](spv_message_level_t level, const char* source, const spv_position_t& position, const char* message) { if (!filterSpvOptimizerMessage(level)) { @@ -961,7 +954,7 @@ std::shared_ptr GLSLPostProcessor::createEmptyOptimizer() { return optimizer; } -std::shared_ptr GLSLPostProcessor::createOptimizer( +std::shared_ptr GLSLPostProcessor::createOptimizer( MaterialBuilder::Optimization optimization, Config const& config) { auto optimizer = createEmptyOptimizer(); @@ -1000,7 +993,7 @@ void GLSLPostProcessor::optimizeSpirv(OptimizerPtr optimizer, SpirvBlob& spirv) } void GLSLPostProcessor::fixupClipDistance( - SpirvBlob& spirv, GLSLPostProcessor::Config const& config) const { + SpirvBlob& spirv, Config const& config) const { if (!config.usesClipDistance) { return; } @@ -1040,7 +1033,7 @@ void GLSLPostProcessor::fixupClipDistance( void GLSLPostProcessor::registerPerformancePasses(Optimizer& optimizer, Config const& config) { - auto RegisterPass = [&](spvtools::Optimizer::PassToken&& pass, + auto RegisterPass = [&](Optimizer::PassToken&& pass, MaterialBuilder::TargetApi apiFilter = MaterialBuilder::TargetApi::ALL) { if (!(config.targetApi & apiFilter)) { return; @@ -1085,7 +1078,7 @@ void GLSLPostProcessor::registerPerformancePasses(Optimizer& optimizer, Config c } void GLSLPostProcessor::registerSizePasses(Optimizer& optimizer, Config const& config) { - auto RegisterPass = [&](spvtools::Optimizer::PassToken&& pass, + auto RegisterPass = [&](Optimizer::PassToken&& pass, MaterialBuilder::TargetApi apiFilter = MaterialBuilder::TargetApi::ALL) { if (!(config.targetApi & apiFilter)) { return; diff --git a/libs/filamat/src/MaterialVariants.cpp b/libs/filamat/src/MaterialVariants.cpp index b6ce7ccd74..2bccf95449 100644 --- a/libs/filamat/src/MaterialVariants.cpp +++ b/libs/filamat/src/MaterialVariants.cpp @@ -16,8 +16,6 @@ #include "MaterialVariants.h" -#include "shaders/ShaderGenerator.h" - #include #include @@ -25,16 +23,8 @@ #include -#include -#include -#include - -#include #include -#include -#include - namespace filamat { std::vector determineSurfaceVariants( @@ -62,58 +52,6 @@ std::vector determineSurfaceVariants( if (fragmentVariant == variant) { variants.emplace_back(variant, filament::backend::ShaderStage::FRAGMENT); } - - // Here we make sure that the combination of vertex and fragment variants have compatible - // PER_VIEW descriptor-set layouts. This could actually be a static/compile-time check - // because it is entirely decided in DescriptorSets.cpp. Unfortunately it's not possible - // to write this entirely as a constexpr. - - if (UTILS_UNLIKELY(vertexVariant != fragmentVariant)) { - // fragment and vertex variants are different, we need to check the layouts are - // compatible. - using filament::ReflectionMode; - using filament::RefractionMode; - using filament::backend::ShaderStage; - - // And we need to do that for all configurations of the "PER_VIEW" descriptor set - // layouts (there are eight). - // See ShaderGenerator::getPerViewDescriptorSetLayoutWithVariant. - for (auto reflection: { - ReflectionMode::SCREEN_SPACE, - ReflectionMode::DEFAULT }) { - for (auto refraction: { - RefractionMode::SCREEN_SPACE, - RefractionMode::CUBEMAP, - RefractionMode::NONE }) { - auto const vdsl = ShaderGenerator::getPerViewDescriptorSetLayoutWithVariant( - vertexVariant, userVariantFilter, isLit || shadowMultiplier, - reflection, refraction); - auto const fdsl = ShaderGenerator::getPerViewDescriptorSetLayoutWithVariant( - fragmentVariant, userVariantFilter, isLit || shadowMultiplier, - reflection, refraction); - // Check that all bindings present in the vertex shader DescriptorSetLayout - // are also present in the fragment shader DescriptorSetLayout. - for (auto const& r: vdsl.bindings) { - if (!hasShaderType(r.stageFlags, ShaderStage::VERTEX)) { - // ignore descriptors that are of the fragment stage only - continue; - } - auto const pos = std::find_if(fdsl.bindings.begin(), fdsl.bindings.end(), - [r](auto const& l) { - return l.count == r.count && l.type == r.type && - l.binding == r.binding && l.flags == r.flags && - l.stageFlags == r.stageFlags; - }); - - // A mismatch is fatal. The material is ill-formed. This typically - // mean a bug / inconsistency in DescriptorsSets.cpp - FILAMENT_CHECK_POSTCONDITION(pos != fdsl.bindings.end()) - << "Variant " << +k << " has mismatched descriptorset layouts"; - } - } - } - } - } return variants; } @@ -133,7 +71,7 @@ std::vector determinePostProcessVariants() { std::vector determineComputeVariants() { // TODO: should we have variants for compute shaders? std::vector variants; - filament::Variant variant(0); + filament::Variant const variant(0); variants.emplace_back(variant, filament::backend::ShaderStage::COMPUTE); return variants; } diff --git a/libs/filamat/src/SamplerBindingMap.cpp b/libs/filamat/src/SamplerBindingMap.cpp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/libs/filamat/src/SamplerBindingMap.h b/libs/filamat/src/SamplerBindingMap.h deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/libs/filamat/src/shaders/ShaderGenerator.cpp b/libs/filamat/src/shaders/ShaderGenerator.cpp index 3c7cd4f7a5..e6fe317385 100644 --- a/libs/filamat/src/shaders/ShaderGenerator.cpp +++ b/libs/filamat/src/shaders/ShaderGenerator.cpp @@ -604,27 +604,13 @@ std::string ShaderGenerator::createSurfaceFragmentProgram(ShaderModel shaderMode if (featureLevel >= FeatureLevel::FEATURE_LEVEL_1) { assert_invariant(mMaterialDomain == MaterialDomain::SURFACE); - - auto const perViewDescriptorSetLayout = getPerViewDescriptorSetLayoutWithVariant( - variant, variantFilter, - material.isLit || material.hasShadowMultiplier, - material.reflectionMode, material.refractionMode); - // this is the list of samplers we need to filter - auto list = SibGenerator::getPerViewSib(variant).getSamplerInfoList(); - - // remove all the samplers that are not included in the descriptor-set layout - list.erase( - std::remove_if(list.begin(), list.end(), - [&perViewDescriptorSetLayout](auto const& entry) { - auto pos = std::find_if( - perViewDescriptorSetLayout.bindings.begin(), - perViewDescriptorSetLayout.bindings.end(), - [&entry](const auto& item) { - return item.binding == entry.binding; - }); - return pos == perViewDescriptorSetLayout.bindings.end(); - }), list.end()); + auto const list = SamplerInterfaceBlock::filterSamplerList( + SibGenerator::getPerViewSib(variant).getSamplerInfoList(), + descriptor_sets::getPerViewDescriptorSetLayoutWithVariant( + variant, mMaterialDomain, variantFilter, + material.isLit || material.hasShadowMultiplier, + material.reflectionMode, material.refractionMode)); cg.generateCommonSamplers(fs, DescriptorSetBindingPoints::PER_VIEW, list); } @@ -841,22 +827,4 @@ bool ShaderGenerator::hasStereo( && featureLevel > MaterialBuilder::FeatureLevel::FEATURE_LEVEL_0; } -backend::DescriptorSetLayout ShaderGenerator::getPerViewDescriptorSetLayoutWithVariant( - filament::Variant variant, - UserVariantFilterMask variantFilter, - bool isLit, - ReflectionMode reflectionMode, - RefractionMode refractionMode) { - if (filament::Variant::isValidDepthVariant(variant)) { - return descriptor_sets::getDepthVariantLayout(); - } - if (filament::Variant::isSSRVariant(variant)) { - return descriptor_sets::getSsrVariantLayout(); - } - // We need to filter out all the descriptors not included in the "resolved" layout below - return descriptor_sets::getPerViewDescriptorSetLayout( - MaterialDomain::SURFACE, variantFilter, - isLit, reflectionMode, refractionMode); -} - } // namespace filament diff --git a/libs/filamat/src/shaders/ShaderGenerator.h b/libs/filamat/src/shaders/ShaderGenerator.h index fd597b13ca..9d9b470a91 100644 --- a/libs/filamat/src/shaders/ShaderGenerator.h +++ b/libs/filamat/src/shaders/ShaderGenerator.h @@ -88,13 +88,6 @@ public: MaterialBuilder::FeatureLevel featureLevel, MaterialInfo const& material) noexcept; - static filament::backend::DescriptorSetLayout getPerViewDescriptorSetLayoutWithVariant( - filament::Variant variant, - filament::UserVariantFilterMask variantFilter, - bool isLit, - filament::ReflectionMode reflectionMode, - filament::RefractionMode refractionMode); - private: static void generateVertexDomainDefines(utils::io::sstream& out, filament::VertexDomain domain) noexcept;