From f57224952ab30e7cb2c9a697b75b2023fbd7f684 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Mon, 22 Aug 2022 16:18:43 -0700 Subject: [PATCH] record sampler informations in the material file The main goal of this change is to have "ugly" code only in filamat. In particular, the sampler binding information is now recorded into the material file and used on the filament side to inform the backend. This means that on the filament side we only have generic code with all the "uglyness" in filamat. In particular SamplerBindingMap and SibGenerator now only exist in filamat. Files of greater interest: Material.cpp, MaterialBuilder.cpp --- RELEASE_NOTES.md | 3 + filament/src/MaterialParser.cpp | 56 ++++++++++++++ filament/src/MaterialParser.h | 15 +++- filament/src/PerViewUniforms.cpp | 2 +- filament/src/components/RenderableManager.cpp | 3 +- filament/src/details/Engine.cpp | 2 +- filament/src/details/Material.cpp | 58 +++++--------- filament/src/details/Material.h | 5 +- filament/src/details/MorphTargetBuffer.cpp | 5 +- filament/src/details/View.cpp | 2 +- libs/filabridge/CMakeLists.txt | 2 - .../include/filament/MaterialChunkType.h | 2 +- .../private/filament/SamplerBindingMap.h | 56 -------------- .../private/filament/SamplerBindingsInfo.h | 51 ++++++++++++ .../private/filament/SamplerInterfaceBlock.h | 16 ++-- .../filament/{SibGenerator.h => SibStructs.h} | 25 ++---- libs/filabridge/src/SamplerInterfaceBlock.cpp | 5 +- libs/filamat/CMakeLists.txt | 2 + libs/filamat/src/GLSLPostProcessor.cpp | 9 +-- libs/filamat/src/MaterialBuilder.cpp | 23 +++--- .../src/SamplerBindingMap.cpp | 61 ++++++++++----- libs/filamat/src/SamplerBindingMap.h | 77 +++++++++++++++++++ .../src/SibGenerator.cpp | 6 +- libs/filamat/src/SibGenerator.h | 41 ++++++++++ .../src/eiff/MaterialInterfaceBlockChunk.cpp | 63 ++++++++++++--- .../src/eiff/MaterialInterfaceBlockChunk.h | 51 ++++++++---- libs/filamat/src/sca/GLSLTools.cpp | 4 - libs/filamat/src/shaders/CodeGenerator.cpp | 18 +---- libs/filamat/src/shaders/MaterialInfo.h | 5 +- libs/filamat/src/shaders/ShaderGenerator.cpp | 2 +- 30 files changed, 454 insertions(+), 216 deletions(-) delete mode 100644 libs/filabridge/include/private/filament/SamplerBindingMap.h create mode 100644 libs/filabridge/include/private/filament/SamplerBindingsInfo.h rename libs/filabridge/include/private/filament/{SibGenerator.h => SibStructs.h} (67%) rename libs/{filabridge => filamat}/src/SamplerBindingMap.cpp (65%) create mode 100644 libs/filamat/src/SamplerBindingMap.h rename libs/{filabridge => filamat}/src/SibGenerator.cpp (97%) create mode 100644 libs/filamat/src/SibGenerator.h diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 0834ca6653..5a48331eec 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -5,6 +5,9 @@ A new header is inserted each time a *tag* is created. ## main branch +- WebGL: reduce max instance count to work around Chrome issues [⚠️ **Recompile Materials**] +- engine: rework material/shader sampler binding code [⚠️ **Recompile Materials**] + ## v1.26.0 - engine: new feature level APIs, see `Engine::getSupportedFeatureLevel()` diff --git a/filament/src/MaterialParser.cpp b/filament/src/MaterialParser.cpp index acfb7a8850..3ffa1ced64 100644 --- a/filament/src/MaterialParser.cpp +++ b/filament/src/MaterialParser.cpp @@ -24,6 +24,7 @@ #include +#include #include #include #include @@ -171,6 +172,17 @@ bool MaterialParser::getUniformBlockBindings( return ChunkUniformBlockBindings::unflatten(unflattener, value); } +bool MaterialParser::getSamplerBlockBindings( + SamplerGroupBindingInfoList* pSamplerGroupInfoList, + SamplerBindingToNameMap* pSamplerBindingToNameMap) const noexcept { + auto type = MaterialSamplerBindings; + const uint8_t* start = mImpl.mChunkContainer.getChunkStart(type); + const uint8_t* end = mImpl.mChunkContainer.getChunkEnd(type); + Unflattener unflattener(start, end); + return ChunkSamplerBlockBindings::unflatten(unflattener, + pSamplerGroupInfoList, pSamplerBindingToNameMap); +} + bool MaterialParser::getDepthWriteSet(bool* value) const noexcept { return mImpl.getFromSimpleChunk(ChunkType::MaterialDepthWriteSet, value); } @@ -486,4 +498,48 @@ bool ChunkUniformBlockBindings::unflatten(filaflat::Unflattener& unflattener, } +bool ChunkSamplerBlockBindings::unflatten(Unflattener& unflattener, + SamplerGroupBindingInfoList* pSamplerGroupBindingInfoList, + SamplerBindingToNameMap* pSamplerBindingToNameMap) { + assert_invariant(pSamplerGroupBindingInfoList && pSamplerBindingToNameMap); + SamplerGroupBindingInfoList& samplerGroupBindingInfoList = *pSamplerGroupBindingInfoList; + SamplerBindingToNameMap& samplerBindingToNameMap = *pSamplerBindingToNameMap; + + uint8_t count; + if (!unflattener.read(&count)) { + return false; + } + assert_invariant(count == utils::Enum::count()); + + UTILS_NOUNROLL + for (size_t i = 0; i < count; i++) { + if (!unflattener.read(&samplerGroupBindingInfoList[i].bindingOffset)) { + return false; + } + if (!unflattener.read((uint8_t *)&samplerGroupBindingInfoList[i].shaderStageFlags)) { + return false; + } + if (!unflattener.read(&samplerGroupBindingInfoList[i].count)) { + return false; + } + } + + if (!unflattener.read(&count)) { + return false; + } + + for (size_t i = 0; i < count; i++) { + uint8_t binding; + if (!unflattener.read(&binding)) { + return false; + } + assert_invariant(binding < backend::MAX_SAMPLER_COUNT); + if (!unflattener.read(&samplerBindingToNameMap[binding])) { + return false; + } + } + + return true; +} + } // namespace filament diff --git a/filament/src/MaterialParser.h b/filament/src/MaterialParser.h index 1f668ce132..48080d7bd6 100644 --- a/filament/src/MaterialParser.h +++ b/filament/src/MaterialParser.h @@ -21,14 +21,17 @@ #include #include -#include #include +#include "../../libs/filamat/src/SamplerBindingMap.h" +#include + +#include + #include #include #include -#include "private/filament/Variant.h" namespace filaflat { class ChunkContainer; @@ -66,6 +69,8 @@ public: bool getShaderModels(uint32_t* value) const noexcept; bool getMaterialProperties(uint64_t* value) const noexcept; bool getUniformBlockBindings(utils::FixedCapacityVector>* value) const noexcept; + bool getSamplerBlockBindings(SamplerGroupBindingInfoList* pSamplerGroupInfoList, + SamplerBindingToNameMap* pSamplerBindingToNameMap) const noexcept; bool getDepthWriteSet(bool* value) const noexcept; bool getDepthWrite(bool* value) const noexcept; @@ -155,6 +160,12 @@ struct ChunkUniformBlockBindings { utils::FixedCapacityVector>* uniformBlockBindings); }; +struct ChunkSamplerBlockBindings { + static bool unflatten(filaflat::Unflattener& unflattener, + SamplerGroupBindingInfoList* pSamplerGroupBindingInfoList, + SamplerBindingToNameMap* pSamplerBindingToNameMap); +}; + } // namespace filament #endif // TNT_FILAMENT_MATERIALPARSER_H diff --git a/filament/src/PerViewUniforms.cpp b/filament/src/PerViewUniforms.cpp index 9b43e88fca..ca56d28446 100644 --- a/filament/src/PerViewUniforms.cpp +++ b/filament/src/PerViewUniforms.cpp @@ -30,7 +30,7 @@ #include #include -#include +#include #include diff --git a/filament/src/components/RenderableManager.cpp b/filament/src/components/RenderableManager.cpp index f7dd6946fd..aab527df23 100644 --- a/filament/src/components/RenderableManager.cpp +++ b/filament/src/components/RenderableManager.cpp @@ -26,7 +26,8 @@ #include "details/Texture.h" #include "details/Material.h" -#include "private/filament/SibGenerator.h" +#include + #include "filament/RenderableManager.h" diff --git a/filament/src/details/Engine.cpp b/filament/src/details/Engine.cpp index 782fe9a51c..9e65b79de3 100644 --- a/filament/src/details/Engine.cpp +++ b/filament/src/details/Engine.cpp @@ -36,7 +36,7 @@ #include "details/VertexBuffer.h" #include "details/View.h" -#include +#include #include diff --git a/filament/src/details/Material.cpp b/filament/src/details/Material.cpp index f7c4c25487..6468c6de8c 100644 --- a/filament/src/details/Material.cpp +++ b/filament/src/details/Material.cpp @@ -16,24 +16,20 @@ #include "details/Material.h" -#include "DFG.h" #include "MaterialParser.h" #include "details/Engine.h" #include "FilamentAPI-impl.h" -#include -#include #include #include #include #include -#include "backend/Program.h" - #include +#include #include #include @@ -127,23 +123,6 @@ Material* Material::Builder::build(Engine& engine) { return upcast(engine).createMaterial(*this); } -static void addSamplerGroup(Program& pb, BindingPoints bindingPoint, - SamplerInterfaceBlock const& sib, SamplerBindingMap const& map) { - const size_t samplerCount = sib.getSize(); - if (samplerCount) { - std::vector samplers(samplerCount); - auto const& list = sib.getSamplerInfoList(); - for (size_t i = 0, c = samplerCount; i < c; ++i) { - CString uniformName( - SamplerInterfaceBlock::getUniformName(sib.getName().c_str(), - list[i].name.c_str())); - uint8_t binding = map.getSamplerBinding(bindingPoint, (uint8_t)i); - samplers[i] = { std::move(uniformName), binding }; - } - pb.setSamplerGroup(+bindingPoint, sib.getStageFlags(), samplers.data(), samplers.size()); - } -} - FMaterial::FMaterial(FEngine& engine, const Material::Builder& builder) : mEngine(engine), mMaterialId(engine.getMaterialId()) @@ -186,6 +165,9 @@ FMaterial::FMaterial(FEngine& engine, const Material::Builder& builder) mUniformBlockBindings.emplace_back(mUniformBlockNames.back().c_str(), item.second); } + success = parser->getSamplerBlockBindings(&mSamplerGroupBindingInfoList, &mSamplerBindingToNameMap); + assert_invariant(success); + #if FILAMENT_ENABLE_MATDBG // Register the material with matdbg. matdbg::DebugServer* server = upcast(engine).debug.server; @@ -200,9 +182,6 @@ FMaterial::FMaterial(FEngine& engine, const Material::Builder& builder) mSubpassInfo.isValid = false; } - // Populate sampler bindings for the backend that will consume this Material. - mSamplerBindings.populate(&mSamplerInterfaceBlock); - parser->getShading(&mShading); parser->getMaterialProperties(&mMaterialProperties); parser->getBlendingMode(&mBlendingMode); @@ -395,25 +374,11 @@ void FMaterial::getSurfaceProgramSlow(Variant variant) const noexcept { Variant fragmentVariant = Variant::filterVariantFragment(variant); Program pb{ getProgramBuilderWithVariants(variant, vertexVariant, fragmentVariant) }; - - // Always add the morphing sampler group because there is no way - // that SamplerBindingMap knows the current variant. - addSamplerGroup(pb, BindingPoints::PER_RENDERABLE_MORPHING, - SibGenerator::getPerRenderPrimitiveMorphingSib(variant), mSamplerBindings); - - addSamplerGroup(pb, BindingPoints::PER_VIEW, SibGenerator::getPerViewSib(variant), mSamplerBindings); - addSamplerGroup(pb, BindingPoints::PER_MATERIAL_INSTANCE, mSamplerInterfaceBlock, mSamplerBindings); - - // getSurfaceBindingIndexMap in GLSLPostProcessor.cpp also needs to update if sampler groups are added. createAndCacheProgram(std::move(pb), variant); } void FMaterial::getPostProcessProgramSlow(Variant variant) const noexcept { Program pb{ getProgramBuilderWithVariants(variant, variant, variant) }; - - addSamplerGroup(pb, BindingPoints::PER_MATERIAL_INSTANCE, mSamplerInterfaceBlock, mSamplerBindings); - - // getPostProcessBindingIndexMap in GLSLPostProcessor.cpp also needs to update if sampler groups are added. createAndCacheProgram(std::move(pb), variant); } @@ -462,6 +427,21 @@ Program FMaterial::getProgramBuilderWithVariants( << ", variant=(" << io::hex << variant.key << io::dec << ")"; }); + UTILS_NOUNROLL + for (size_t i = 0; i < Enum::count(); i++) { + BindingPoints bindingPoint = (BindingPoints)i; + auto const& info = mSamplerGroupBindingInfoList[i]; + if (info.count) { + std::array samplers{}; + for (size_t j = 0, c = info.count; j < c; ++j) { + uint8_t binding = info.bindingOffset + j; + samplers[j] = { mSamplerBindingToNameMap[binding], binding }; + } + program.setSamplerGroup(+bindingPoint, info.shaderStageFlags, + samplers.data(), info.count); + } + } + return program; } diff --git a/filament/src/details/Material.h b/filament/src/details/Material.h index 76a753c096..e873439701 100644 --- a/filament/src/details/Material.h +++ b/filament/src/details/Material.h @@ -23,7 +23,7 @@ #include -#include +#include #include #include #include @@ -226,9 +226,10 @@ private: SamplerInterfaceBlock mSamplerInterfaceBlock; UniformInterfaceBlock mUniformInterfaceBlock; SubpassInfo mSubpassInfo; - SamplerBindingMap mSamplerBindings; utils::FixedCapacityVector> mUniformBlockBindings; utils::FixedCapacityVector mUniformBlockNames; + SamplerGroupBindingInfoList mSamplerGroupBindingInfoList; + SamplerBindingToNameMap mSamplerBindingToNameMap; #if FILAMENT_ENABLE_MATDBG matdbg::MaterialKey mDebuggerId; diff --git a/filament/src/details/MorphTargetBuffer.cpp b/filament/src/details/MorphTargetBuffer.cpp index 4e9a39f197..216283a3cb 100644 --- a/filament/src/details/MorphTargetBuffer.cpp +++ b/filament/src/details/MorphTargetBuffer.cpp @@ -16,14 +16,13 @@ #include "details/MorphTargetBuffer.h" -#include "private/filament/SibGenerator.h" +#include -#include "details/Engine.h" +#include
#include "FilamentAPI-impl.h" #include - #include namespace filament { diff --git a/filament/src/details/View.cpp b/filament/src/details/View.cpp index 7883ca2c7b..c811b286e8 100644 --- a/filament/src/details/View.cpp +++ b/filament/src/details/View.cpp @@ -32,7 +32,7 @@ #include #include -#include +#include #include #include diff --git a/libs/filabridge/CMakeLists.txt b/libs/filabridge/CMakeLists.txt index 6c01a03dc2..4e4f25e258 100644 --- a/libs/filabridge/CMakeLists.txt +++ b/libs/filabridge/CMakeLists.txt @@ -10,9 +10,7 @@ set(PUBLIC_HDR_DIR include) file(GLOB_RECURSE PUBLIC_HDRS ${PUBLIC_HDR_DIR}/**/*.h) set(SRCS - src/SamplerBindingMap.cpp src/SamplerInterfaceBlock.cpp - src/SibGenerator.cpp src/UniformInterfaceBlock.cpp src/Variant.cpp ) diff --git a/libs/filabridge/include/filament/MaterialChunkType.h b/libs/filabridge/include/filament/MaterialChunkType.h index ec74d5b167..c63b7d5414 100644 --- a/libs/filabridge/include/filament/MaterialChunkType.h +++ b/libs/filabridge/include/filament/MaterialChunkType.h @@ -45,7 +45,7 @@ enum UTILS_PUBLIC ChunkType : uint64_t { MaterialSpirv = charTo64bitNum("MAT_SPIR"), MaterialMetal = charTo64bitNum("MAT_METL"), MaterialShaderModels = charTo64bitNum("MAT_SMDL"), - MaterialSamplerBindings = charTo64bitNum("MAT_SAMP"), // no longer used + MaterialSamplerBindings = charTo64bitNum("MAT_SAMP"), MaterialUniformBindings = charTo64bitNum("MAT_UNIF"), MaterialProperties = charTo64bitNum("MAT_PROP"), diff --git a/libs/filabridge/include/private/filament/SamplerBindingMap.h b/libs/filabridge/include/private/filament/SamplerBindingMap.h deleted file mode 100644 index d5bdefbbff..0000000000 --- a/libs/filabridge/include/private/filament/SamplerBindingMap.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef TNT_FILAMENT_DRIVER_SAMPLERBINDINGMAP_H -#define TNT_FILAMENT_DRIVER_SAMPLERBINDINGMAP_H - -#include - -namespace filament { - -class SamplerInterfaceBlock; - -// Lookup table from (BlockIndex,LocalOffset) to (GlobalOffset,GroupIndex). -// Also stores the mapping as a flat vector of 4-tuples to make it easy to [de]serialize. -class SamplerBindingMap { -public: - // Assigns a range of finalized binding points to each sampler block. - // If a per-material SIB is provided, then material samplers are also inserted (always at the - // end). The optional material name is used for error reporting only. - void populate(const SamplerInterfaceBlock* perMaterialSib = nullptr, - const char* materialName = nullptr); - - // Given a valid Filament binding point and an offset within the block, returns a global unique - // binding index. - uint8_t getSamplerBinding(BindingPoints bindingPoint, uint8_t localOffset) const { - assert_invariant(mSamplerBlockOffsets[+bindingPoint] != UNKNOWN_OFFSET); - return mSamplerBlockOffsets[+bindingPoint] + localOffset; - } - - // Gets the global offset of the first sampler in the given sampler block. - uint8_t getBlockOffset(BindingPoints bindingPoint) const { - assert_invariant(mSamplerBlockOffsets[+bindingPoint] != UNKNOWN_OFFSET); - return mSamplerBlockOffsets[+bindingPoint]; - } - -private: - constexpr static uint8_t UNKNOWN_OFFSET = 0xff; - uint8_t mSamplerBlockOffsets[utils::Enum::count()] = { UNKNOWN_OFFSET }; -}; - -} // namespace filament - -#endif // TNT_FILAMENT_DRIVER_SAMPLERBINDINGMAP_H diff --git a/libs/filabridge/include/private/filament/SamplerBindingsInfo.h b/libs/filabridge/include/private/filament/SamplerBindingsInfo.h new file mode 100644 index 0000000000..28bfe19b13 --- /dev/null +++ b/libs/filabridge/include/private/filament/SamplerBindingsInfo.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef TNT_FILABRIDGE_SAMPLERBINDINGS_INFO_H +#define TNT_FILABRIDGE_SAMPLERBINDINGS_INFO_H + +#include + +#include + +#include + +#include + +namespace filament { + +// binding information about a sampler group +struct SamplerGroupBindingInfo { + constexpr static uint8_t UNKNOWN_OFFSET = 0xff; + // global binding of this block, or UNKNOWN_OFFSET if not used. + uint8_t bindingOffset = UNKNOWN_OFFSET; + // shader stage flags for samplers in this block + backend::ShaderStageFlags shaderStageFlags = backend::ShaderStageFlags::NONE; + // number of samplers in this block. Can be zero. + uint8_t count = 0; +}; + +// list of binding information for all known binding points +using SamplerGroupBindingInfoList = + std::array()>; + +// map of sampler shader binding to sampler shader name +using SamplerBindingToNameMap = + std::array; + +} // namespace filament + +#endif //TNT_FILABRIDGE_SAMPLERBINDINGS_INFO_H diff --git a/libs/filabridge/include/private/filament/SamplerInterfaceBlock.h b/libs/filabridge/include/private/filament/SamplerInterfaceBlock.h index 94b2478096..1e2a9e8bd1 100644 --- a/libs/filabridge/include/private/filament/SamplerInterfaceBlock.h +++ b/libs/filabridge/include/private/filament/SamplerInterfaceBlock.h @@ -48,12 +48,13 @@ public: using SamplerParams = backend::SamplerParams; struct SamplerInfo { // NOLINT(cppcoreguidelines-pro-type-member-init) - utils::CString name; // name of this sampler - uint8_t offset; // offset in "Sampler" of this sampler in the buffer - Type type; // type of this sampler - Format format; // format of this sampler - Precision precision; // precision of this sampler - bool multisample; // multisample capable + utils::CString name; // name of this sampler + utils::CString uniformName; // name of the uniform holding this sampler (needed for glsl) + uint8_t offset; // offset in "Sampler" of this sampler in the buffer + Type type; // type of this sampler + Format format; // format of this sampler + Precision precision; // precision of this sampler + bool multisample; // multisample capable }; class Builder { @@ -114,11 +115,12 @@ public: bool isEmpty() const noexcept { return mSamplersInfoList.empty(); } - static utils::CString getUniformName(const char* group, const char* sampler) noexcept; + static utils::CString generateUniformName(const char* group, const char* sampler) noexcept; private: friend class Builder; + explicit SamplerInterfaceBlock(Builder const& builder) noexcept; utils::CString mName; diff --git a/libs/filabridge/include/private/filament/SibGenerator.h b/libs/filabridge/include/private/filament/SibStructs.h similarity index 67% rename from libs/filabridge/include/private/filament/SibGenerator.h rename to libs/filabridge/include/private/filament/SibStructs.h index 54fdcbb5f9..2d4ca033e9 100644 --- a/libs/filabridge/include/private/filament/SibGenerator.h +++ b/libs/filabridge/include/private/filament/SibStructs.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 The Android Open Source Project + * Copyright (C) 2022 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,28 +14,14 @@ * limitations under the License. */ -#ifndef TNT_FILABRIDGE_SIBGENERATOR_H -#define TNT_FILABRIDGE_SIBGENERATOR_H - -#include +#ifndef TNT_FILABRIDGE_SIBSTRUCTS_H +#define TNT_FILABRIDGE_SIBSTRUCTS_H #include #include -#include "EngineEnums.h" namespace filament { -class SamplerInterfaceBlock; - -class SibGenerator { -public: - static SamplerInterfaceBlock const& getPerViewSib(Variant variant) noexcept; - static SamplerInterfaceBlock const& getPerRenderPrimitiveMorphingSib(Variant variant) noexcept; - static SamplerInterfaceBlock const* getSib(filament::BindingPoints bindingPoint, Variant variant) noexcept; - // When adding a sampler block here, make sure to also update - // FMaterial::getSurfaceProgramSlow and FMaterial::getPostProcessProgramSlow if needed -}; - struct PerViewSib { // indices of each sampler in this SamplerInterfaceBlock (see: getPerViewSib()) static constexpr size_t SHADOW_MAP = 0; // user defined (1024x1024) DEPTH, array @@ -56,5 +42,6 @@ struct PerRenderPrimitiveMorphingSib { static constexpr size_t SAMPLER_COUNT = 2; }; -} -#endif // TNT_FILABRIDGE_SIBGENERATOR_H +} // namespace filament + +#endif //TNT_FILABRIDGE_SIBSTRUCTS_H diff --git a/libs/filabridge/src/SamplerInterfaceBlock.cpp b/libs/filabridge/src/SamplerInterfaceBlock.cpp index f40ddf175f..09c70a240b 100644 --- a/libs/filabridge/src/SamplerInterfaceBlock.cpp +++ b/libs/filabridge/src/SamplerInterfaceBlock.cpp @@ -46,7 +46,7 @@ SamplerInterfaceBlock::Builder& SamplerInterfaceBlock::Builder::add( std::string_view samplerName, Type type, Format format, Precision precision, bool multisample) noexcept { mEntries.push_back({ - { samplerName.data(), samplerName.size() }, + { samplerName.data(), samplerName.size() }, { }, uint8_t(mEntries.size()), type, format, precision, multisample }); return *this; } @@ -84,6 +84,7 @@ SamplerInterfaceBlock::SamplerInterfaceBlock(Builder const& builder) noexcept assert_invariant(i == e.offset); SamplerInfo& info = samplersInfoList[i++]; info = e; + info.uniformName = generateUniformName(mName.c_str(), e.name.c_str()); infoMap[{ info.name.data(), info.name.size() }] = info.offset; // info.name.c_str() guaranteed constant } assert_invariant(i == samplersInfoList.size()); @@ -97,7 +98,7 @@ const SamplerInterfaceBlock::SamplerInfo* SamplerInterfaceBlock::getSamplerInfo( return &mSamplersInfoList[pos->second]; } -utils::CString SamplerInterfaceBlock::getUniformName(const char* group, const char* sampler) noexcept { +utils::CString SamplerInterfaceBlock::generateUniformName(const char* group, const char* sampler) noexcept { char uniformName[256]; // sampler interface block name diff --git a/libs/filamat/CMakeLists.txt b/libs/filamat/CMakeLists.txt index edc22be8d7..d0695a76bc 100644 --- a/libs/filamat/CMakeLists.txt +++ b/libs/filamat/CMakeLists.txt @@ -43,6 +43,8 @@ set(COMMON_SRCS src/Includes.cpp src/MaterialBuilder.cpp src/MaterialVariants.cpp + src/SamplerBindingMap.cpp + src/SibGenerator.cpp src/UibGenerator.cpp ) diff --git a/libs/filamat/src/GLSLPostProcessor.cpp b/libs/filamat/src/GLSLPostProcessor.cpp index ecb71b8ee9..0b68d80e11 100644 --- a/libs/filamat/src/GLSLPostProcessor.cpp +++ b/libs/filamat/src/GLSLPostProcessor.cpp @@ -29,7 +29,7 @@ #include #include -#include +#include "SibGenerator.h" #include @@ -55,15 +55,10 @@ UTILS_NOINLINE static void generateBindingIndexMap(const GLSLPostProcessor::Config& config, SamplerInterfaceBlock const& sib, BindingIndexMap& map) { const auto stageFlags = sib.getStageFlags(); - - - if (hasShaderType(stageFlags, config.shaderType)) { const auto& infoList = sib.getSamplerInfoList(); for (const auto& info: infoList) { - auto uniformName = SamplerInterfaceBlock::getUniformName( - sib.getName().c_str(), info.name.c_str()); - map[uniformName.c_str()] = map.size(); + map[info.uniformName.c_str()] = map.size(); } } } diff --git a/libs/filamat/src/MaterialBuilder.cpp b/libs/filamat/src/MaterialBuilder.cpp index 64156e7a1a..62248291d7 100644 --- a/libs/filamat/src/MaterialBuilder.cpp +++ b/libs/filamat/src/MaterialBuilder.cpp @@ -29,7 +29,7 @@ #include #include -#include +#include "SibGenerator.h" #include "MaterialVariants.h" @@ -972,7 +972,7 @@ Package MaterialBuilder::build(JobSystem& jobSystem) noexcept { return Package::invalidPackage(); } - info.samplerBindings.populate(&info.sib, mMaterialName.c_str()); + info.samplerBindings.init(mMaterialDomain, &info.sib, mMaterialName.c_str()); // Create chunk tree. ChunkContainer container; @@ -1030,7 +1030,7 @@ std::string MaterialBuilder::peek(filament::backend::ShaderType type, MaterialInfo info; prepareToBuild(info); - info.samplerBindings.populate(&info.sib, mMaterialName.c_str()); + info.samplerBindings.init(mMaterialDomain, &info.sib, mMaterialName.c_str()); if (type == filament::backend::ShaderType::VERTEX) { return sg.createVertexProgram(ShaderModel(params.shaderModel), @@ -1047,8 +1047,6 @@ void MaterialBuilder::writeCommonChunks(ChunkContainer& container, MaterialInfo& container.addSimpleChild(ChunkType::MaterialName, mMaterialName.c_str_safe()); container.addSimpleChild(ChunkType::MaterialShaderModels, mShaderModels.getValue()); container.addSimpleChild(ChunkType::MaterialDomain, static_cast(mMaterialDomain)); - container.addSimpleChild(ChunkType::MaterialRefraction, static_cast(mRefractionMode)); - container.addSimpleChild(ChunkType::MaterialRefractionType, static_cast(mRefractionType)); // note: this chunk is only needed for OpenGL backends, which don't all support layout(binding=) using namespace filament; @@ -1064,18 +1062,22 @@ void MaterialBuilder::writeCommonChunks(ChunkContainer& container, MaterialInfo& }; container.addChild(std::move(list)); - // UIB + // note: this chunk is needed for Vulkan and GL backends. Metal shouldn't need it (but + // still does as of now). + container.addChild(info.samplerBindings); + + // User Material UIB container.addChild(info.uib); - // SIB + // User Material SIB container.addChild(info.sib); - // Subpass + // User Subpass container.addChild(info.subpass); + container.addSimpleChild(ChunkType::MaterialDoubleSidedSet, mDoubleSidedCapability); container.addSimpleChild(ChunkType::MaterialDoubleSided, mDoubleSided); - container.addSimpleChild(ChunkType::MaterialBlendingMode, static_cast(mBlendingMode)); container.addSimpleChild(ChunkType::MaterialTransparencyMode, static_cast(mTransparencyMode)); container.addSimpleChild(ChunkType::MaterialReflectionMode, static_cast(mReflectionMode)); @@ -1087,6 +1089,7 @@ void MaterialBuilder::writeCommonChunks(ChunkContainer& container, MaterialInfo& container.addSimpleChild(ChunkType::MaterialCullingMode, static_cast(mCullingMode)); uint64_t properties = 0; + UTILS_NOUNROLL for (size_t i = 0; i < MATERIAL_PROPERTIES_COUNT; i++) { if (mProperties[i]) { properties |= uint64_t(1u) << i; @@ -1106,6 +1109,8 @@ void MaterialBuilder::writeSurfaceChunks(ChunkContainer& container) const noexce container.addSimpleChild(ChunkType::MaterialShadowMultiplier, mShadowMultiplier); } + container.addSimpleChild(ChunkType::MaterialRefraction, static_cast(mRefractionMode)); + container.addSimpleChild(ChunkType::MaterialRefractionType, static_cast(mRefractionType)); container.addSimpleChild(ChunkType::MaterialClearCoatIorChange, mClearCoatIorChange); container.addSimpleChild(ChunkType::MaterialRequiredAttributes, mRequiredAttributes.getValue()); container.addSimpleChild(ChunkType::MaterialSpecularAntiAliasing, mSpecularAntiAliasing); diff --git a/libs/filabridge/src/SamplerBindingMap.cpp b/libs/filamat/src/SamplerBindingMap.cpp similarity index 65% rename from libs/filabridge/src/SamplerBindingMap.cpp rename to libs/filamat/src/SamplerBindingMap.cpp index 8aabcd347c..ef6b12fdfa 100644 --- a/libs/filabridge/src/SamplerBindingMap.cpp +++ b/libs/filamat/src/SamplerBindingMap.cpp @@ -14,11 +14,14 @@ * limitations under the License. */ -#include "private/filament/SamplerBindingMap.h" +#include "SamplerBindingMap.h" -#include "private/filament/SamplerInterfaceBlock.h" +#include "SibGenerator.h" -#include +#include + +#include +#include #include @@ -45,36 +48,58 @@ static const char* to_string(ShaderStageFlags stageFlags) noexcept { return nullptr; } -void SamplerBindingMap::populate(const SamplerInterfaceBlock* perMaterialSib, - const char* materialName) { - // TODO: Calculate SamplerBindingMap with a material variant. - // The dummy variant isn't enough for calculating the binding map. - // The material variant affects sampler bindings. - const Variant dummyVariant{}; +void SamplerBindingMap::init(MaterialDomain materialDomain, + const SamplerInterfaceBlock* perMaterialSib, const char* materialName) { + + assert_invariant(mActiveSamplerCount == 0); + + // Note: the material variant affects only the sampler types, but cannot affect + // the actual bindings. For this reason it is okay to use the dummyVariant here. uint8_t offset = 0; size_t vertexSamplerCount = 0; size_t fragmentSamplerCount = 0; - UTILS_NOUNROLL - for (size_t blockIndex = 0; blockIndex < Enum::count(); blockIndex++) { - mSamplerBlockOffsets[blockIndex] = offset; + auto processSamplerGroup = [&](BindingPoints bindingPoint){ SamplerInterfaceBlock const* const sib = - (blockIndex == BindingPoints::PER_MATERIAL_INSTANCE) ? - perMaterialSib : SibGenerator::getSib(BindingPoints(blockIndex), dummyVariant); + (bindingPoint == BindingPoints::PER_MATERIAL_INSTANCE) ? + perMaterialSib : SibGenerator::getSib(bindingPoint, {}); if (sib) { - const auto& sibFields = sib->getSamplerInfoList(); const auto stageFlags = sib->getStageFlags(); - const size_t samplerCount = sibFields.size(); - offset += samplerCount; + auto const& list = sib->getSamplerInfoList(); + const size_t samplerCount = list.size(); + if (any(stageFlags & ShaderStageFlags::VERTEX)) { vertexSamplerCount += samplerCount; } if (any(stageFlags & ShaderStageFlags::FRAGMENT)) { fragmentSamplerCount += samplerCount; } + + mSamplerBlockOffsets[+bindingPoint] = { offset, stageFlags, uint8_t(samplerCount) }; + for (size_t i = 0; i < samplerCount; i++) { + assert_invariant(mSamplerNamesBindingMap[offset + i].empty()); + mSamplerNamesBindingMap[offset + i] = list[i].uniformName; + } + + offset += samplerCount; } + }; + + switch(materialDomain) { + case MaterialDomain::SURFACE: + UTILS_NOUNROLL + for (size_t i = 0; i < Enum::count(); i++) { + processSamplerGroup((BindingPoints)i); + } + break; + case MaterialDomain::POST_PROCESS: + processSamplerGroup(BindingPoints::PER_MATERIAL_INSTANCE); + break; } + mActiveSamplerCount = offset; + + // TODO: update this check for feature level 2 const bool isOverflow = vertexSamplerCount > MAX_VERTEX_SAMPLER_COUNT || fragmentSamplerCount > MAX_FRAGMENT_SAMPLER_COUNT; @@ -93,7 +118,7 @@ void SamplerBindingMap::populate(const SamplerInterfaceBlock* perMaterialSib, for (size_t blockIndex = 0; blockIndex < Enum::count(); blockIndex++) { SamplerInterfaceBlock const* const sib = (blockIndex == BindingPoints::PER_MATERIAL_INSTANCE) ? - perMaterialSib : SibGenerator::getSib(BindingPoints(blockIndex), dummyVariant); + perMaterialSib : SibGenerator::getSib(BindingPoints(blockIndex), {}); if (sib) { auto const& sibFields = sib->getSamplerInfoList(); auto const stageFlagsAsString = to_string(sib->getStageFlags()); diff --git a/libs/filamat/src/SamplerBindingMap.h b/libs/filamat/src/SamplerBindingMap.h new file mode 100644 index 0000000000..fee6a5c28f --- /dev/null +++ b/libs/filamat/src/SamplerBindingMap.h @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef TNT_FILAMENT_DRIVER_SAMPLERBINDINGMAP_H +#define TNT_FILAMENT_DRIVER_SAMPLERBINDINGMAP_H + +#include + +#include + +namespace filament { + +class SamplerInterfaceBlock; + +/* + * SamplerBindingMap maps filament's (BindingPoints, offset) to a global offset. + * This global offset is used in shaders to set the `layout(binding=` of each sampler. + * + * It also keeps a map of global offsets to the sampler name in the shader. + * + * SamplerBindingMap is flattened into the material file and used on the filament side to + * create the backend's programs. + */ +class SamplerBindingMap { +public: + + using SamplerGroupBindingInfo = SamplerGroupBindingInfo; + + // Initializes the SamplerBindingMap. + // Assigns a range of finalized binding points to each sampler block. + // If a per-material SIB is provided, then material samplers are also inserted (always at the + // end). The optional material name is used for error reporting only. + void init(MaterialDomain materialDomain, + const SamplerInterfaceBlock* perMaterialSib = nullptr, + const char* materialName = nullptr); + + SamplerGroupBindingInfo const& getSamplerGroupBindingInfo(BindingPoints bindingPoint) const noexcept { + return mSamplerBlockOffsets[+bindingPoint]; + } + + // Gets the global offset of the first sampler in the given sampler block. + inline uint8_t getBlockOffset(BindingPoints bindingPoint) const noexcept { + assert_invariant(mSamplerBlockOffsets[+bindingPoint].bindingOffset != UNKNOWN_OFFSET); + return getSamplerGroupBindingInfo(bindingPoint).bindingOffset; + } + + size_t getActiveSamplerCount() const noexcept { + return mActiveSamplerCount; + } + + utils::CString const& getSamplerName(size_t binding) const noexcept { + return mSamplerNamesBindingMap[binding]; + } + +private: + constexpr static uint8_t UNKNOWN_OFFSET = SamplerGroupBindingInfo::UNKNOWN_OFFSET; + SamplerGroupBindingInfoList mSamplerBlockOffsets{}; + SamplerBindingToNameMap mSamplerNamesBindingMap{}; + uint8_t mActiveSamplerCount = 0; +}; + +} // namespace filament + +#endif // TNT_FILAMENT_DRIVER_SAMPLERBINDINGMAP_H diff --git a/libs/filabridge/src/SibGenerator.cpp b/libs/filamat/src/SibGenerator.cpp similarity index 97% rename from libs/filabridge/src/SibGenerator.cpp rename to libs/filamat/src/SibGenerator.cpp index 37072bdc52..ac105c45ef 100644 --- a/libs/filabridge/src/SibGenerator.cpp +++ b/libs/filamat/src/SibGenerator.cpp @@ -14,12 +14,12 @@ * limitations under the License. */ -#include "private/filament/SibGenerator.h" +#include "SibGenerator.h" #include "private/filament/Variant.h" #include "private/filament/EngineEnums.h" - -#include +#include "private/filament/SamplerInterfaceBlock.h" +#include "private/filament/SibStructs.h" namespace filament { diff --git a/libs/filamat/src/SibGenerator.h b/libs/filamat/src/SibGenerator.h new file mode 100644 index 0000000000..64382686e1 --- /dev/null +++ b/libs/filamat/src/SibGenerator.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef TNT_FILABRIDGE_SIBGENERATOR_H +#define TNT_FILABRIDGE_SIBGENERATOR_H + +#include "private/filament/Variant.h" + +#include +#include +#include "private/filament/EngineEnums.h" + +namespace filament { + +class SamplerInterfaceBlock; + +class SibGenerator { +public: + static SamplerInterfaceBlock const& getPerViewSib(Variant variant) noexcept; + static SamplerInterfaceBlock const& getPerRenderPrimitiveMorphingSib(Variant variant) noexcept; + static SamplerInterfaceBlock const* getSib(filament::BindingPoints bindingPoint, Variant variant) noexcept; + // When adding a sampler block here, make sure to also update + // FMaterial::getSurfaceProgramSlow and FMaterial::getPostProcessProgramSlow if needed +}; + +} // namespace filament + +#endif // TNT_FILABRIDGE_SIBGENERATOR_H diff --git a/libs/filamat/src/eiff/MaterialInterfaceBlockChunk.cpp b/libs/filamat/src/eiff/MaterialInterfaceBlockChunk.cpp index 4e6d62d01a..e263fbf8e9 100644 --- a/libs/filamat/src/eiff/MaterialInterfaceBlockChunk.cpp +++ b/libs/filamat/src/eiff/MaterialInterfaceBlockChunk.cpp @@ -15,20 +15,26 @@ */ #include "MaterialInterfaceBlockChunk.h" -#include - #include "filament/MaterialChunkType.h" +#include "../SamplerBindingMap.h" +#include +#include +#include + +#include + using namespace filament; namespace filamat { -MaterialUniformInterfaceBlockChunk::MaterialUniformInterfaceBlockChunk(UniformInterfaceBlock& uib) : +MaterialUniformInterfaceBlockChunk::MaterialUniformInterfaceBlockChunk( + UniformInterfaceBlock const& uib) : Chunk(ChunkType::MaterialUib), - mUib(uib){ + mUib(uib) { } -void MaterialUniformInterfaceBlockChunk::flatten(Flattener &f) { +void MaterialUniformInterfaceBlockChunk::flatten(Flattener& f) { f.writeString(mUib.getName()); auto uibFields = mUib.getUniformInfoList(); f.writeUint64(uibFields.size()); @@ -40,12 +46,15 @@ void MaterialUniformInterfaceBlockChunk::flatten(Flattener &f) { } } -MaterialSamplerInterfaceBlockChunk::MaterialSamplerInterfaceBlockChunk(SamplerInterfaceBlock& sib) : +// ------------------------------------------------------------------------------------------------ + +MaterialSamplerInterfaceBlockChunk::MaterialSamplerInterfaceBlockChunk( + SamplerInterfaceBlock const& sib) : Chunk(ChunkType::MaterialSib), mSib(sib) { } -void MaterialSamplerInterfaceBlockChunk::flatten(Flattener &f) { +void MaterialSamplerInterfaceBlockChunk::flatten(Flattener& f) { f.writeString(mSib.getName().c_str()); auto sibFields = mSib.getSamplerInfoList(); f.writeUint64(sibFields.size()); @@ -58,12 +67,14 @@ void MaterialSamplerInterfaceBlockChunk::flatten(Flattener &f) { } } -MaterialSubpassInterfaceBlockChunk::MaterialSubpassInterfaceBlockChunk(SubpassInfo& subpass) : +// ------------------------------------------------------------------------------------------------ + +MaterialSubpassInterfaceBlockChunk::MaterialSubpassInterfaceBlockChunk(SubpassInfo const& subpass) : Chunk(ChunkType::MaterialSubpass), mSubpass(subpass) { } -void MaterialSubpassInterfaceBlockChunk::flatten(Flattener &f) { +void MaterialSubpassInterfaceBlockChunk::flatten(Flattener& f) { f.writeString(mSubpass.block.c_str()); f.writeUint64(mSubpass.isValid ? 1 : 0); // only ever a single subpass for now if (mSubpass.isValid) { @@ -76,6 +87,8 @@ void MaterialSubpassInterfaceBlockChunk::flatten(Flattener &f) { } } +// ------------------------------------------------------------------------------------------------ + MaterialUniformBlockBindingsChunk::MaterialUniformBlockBindingsChunk( utils::FixedCapacityVector> list) : Chunk(ChunkType::MaterialUniformBindings), @@ -90,4 +103,36 @@ void MaterialUniformBlockBindingsChunk::flatten(Flattener& f) { } } +// ------------------------------------------------------------------------------------------------ + +MaterialSamplerBlockBindingChunk::MaterialSamplerBlockBindingChunk( + SamplerBindingMap const& samplerBindings) + : Chunk(ChunkType::MaterialSamplerBindings), + mSamplerBindings(samplerBindings) { +} + +void MaterialSamplerBlockBindingChunk::flatten(Flattener& f) { + f.writeUint8(utils::Enum::count()); + UTILS_NOUNROLL + for (size_t i = 0; i < utils::Enum::count(); i++) { + BindingPoints bindingPoint = (BindingPoints)i; + auto const& bindingInfo = mSamplerBindings.getSamplerGroupBindingInfo(bindingPoint); + f.writeUint8(bindingInfo.bindingOffset); + f.writeUint8((uint8_t)bindingInfo.shaderStageFlags); + f.writeUint8(bindingInfo.count); + } + f.writeUint8(mSamplerBindings.getActiveSamplerCount()); + UTILS_UNUSED_IN_RELEASE size_t c = 0; + UTILS_NOUNROLL + for (size_t i = 0; i < backend::MAX_SAMPLER_COUNT; i++) { + auto const& uniformName = mSamplerBindings.getSamplerName(i); + if (!uniformName.empty()) { + f.writeUint8((uint8_t)i); + f.writeString(uniformName.c_str()); + c++; + } + } + assert_invariant(c == mSamplerBindings.getActiveSamplerCount()); +} + } // namespace filamat diff --git a/libs/filamat/src/eiff/MaterialInterfaceBlockChunk.h b/libs/filamat/src/eiff/MaterialInterfaceBlockChunk.h index b9f3da2529..6fe71fcfe4 100644 --- a/libs/filamat/src/eiff/MaterialInterfaceBlockChunk.h +++ b/libs/filamat/src/eiff/MaterialInterfaceBlockChunk.h @@ -20,45 +20,57 @@ #include "Chunk.h" #include -#include -#include -#include + +#include + +namespace filament { +class SamplerBindingMap; +class SamplerInterfaceBlock; +class UniformInterfaceBlock; +struct SubpassInfo; +} // namespace filament namespace filamat { class MaterialUniformInterfaceBlockChunk final : public Chunk { public: - explicit MaterialUniformInterfaceBlockChunk(filament::UniformInterfaceBlock& uib); + explicit MaterialUniformInterfaceBlockChunk(filament::UniformInterfaceBlock const& uib); ~MaterialUniformInterfaceBlockChunk() final = default; private: - void flatten(Flattener &) final; + void flatten(Flattener&) final; - filament::UniformInterfaceBlock& mUib; + filament::UniformInterfaceBlock const& mUib; }; +// ------------------------------------------------------------------------------------------------ + class MaterialSamplerInterfaceBlockChunk final : public Chunk { public: - explicit MaterialSamplerInterfaceBlockChunk(filament::SamplerInterfaceBlock& sib); + explicit MaterialSamplerInterfaceBlockChunk(filament::SamplerInterfaceBlock const& sib); ~MaterialSamplerInterfaceBlockChunk() final = default; private: - void flatten(Flattener &) final; + void flatten(Flattener&) final; - filament::SamplerInterfaceBlock& mSib; + filament::SamplerInterfaceBlock const& mSib; }; +// ------------------------------------------------------------------------------------------------ + class MaterialSubpassInterfaceBlockChunk final : public Chunk { public: - explicit MaterialSubpassInterfaceBlockChunk(filament::SubpassInfo& subpass); + explicit MaterialSubpassInterfaceBlockChunk(filament::SubpassInfo const& subpass); ~MaterialSubpassInterfaceBlockChunk() final = default; private: - void flatten(Flattener &) final; + void flatten(Flattener&) final; - filament::SubpassInfo& mSubpass; + filament::SubpassInfo const& mSubpass; }; +// ------------------------------------------------------------------------------------------------ + class MaterialUniformBlockBindingsChunk final : public Chunk { public: explicit MaterialUniformBlockBindingsChunk( @@ -66,11 +78,24 @@ public: ~MaterialUniformBlockBindingsChunk() final = default; private: - void flatten(Flattener &) final; + void flatten(Flattener&) final; utils::FixedCapacityVector> mBindingList; }; +// ------------------------------------------------------------------------------------------------ + +class MaterialSamplerBlockBindingChunk final : public Chunk { +public: + explicit MaterialSamplerBlockBindingChunk(filament::SamplerBindingMap const& samplerBindings); + ~MaterialSamplerBlockBindingChunk() final = default; + +private: + void flatten(Flattener &) final; + + filament::SamplerBindingMap const& mSamplerBindings; +}; + } // namespace filamat #endif // TNT_FILAMAT_MAT_INTEFFACE_BLOCK_CHUNK_H diff --git a/libs/filamat/src/sca/GLSLTools.cpp b/libs/filamat/src/sca/GLSLTools.cpp index 4421753ded..5ab541446e 100644 --- a/libs/filamat/src/sca/GLSLTools.cpp +++ b/libs/filamat/src/sca/GLSLTools.cpp @@ -16,11 +16,7 @@ #include "GLSLTools.h" -#include - #include -#include -#include #include #include "../shaders/MaterialInfo.h" diff --git a/libs/filamat/src/shaders/CodeGenerator.cpp b/libs/filamat/src/shaders/CodeGenerator.cpp index 126f5025df..03fbbdbeb6 100644 --- a/libs/filamat/src/shaders/CodeGenerator.cpp +++ b/libs/filamat/src/shaders/CodeGenerator.cpp @@ -361,11 +361,6 @@ io::sstream& CodeGenerator::generateSamplers( } for (auto const& info : infos) { - - CString uniformName = - SamplerInterfaceBlock::getUniformName( - sib.getName().c_str(), info.name.c_str()); - auto type = info.type; if (type == SamplerType::SAMPLER_EXTERNAL && mShaderModel != ShaderModel::MOBILE) { // we're generating the shader for the desktop, where we assume external textures @@ -392,7 +387,7 @@ io::sstream& CodeGenerator::generateSamplers( out << ") "; } - out << "uniform " << precision << " " << typeName << " " << uniformName.c_str(); + out << "uniform " << precision << " " << typeName << " " << info.uniformName.c_str(); out << ";\n"; } out << "\n"; @@ -406,7 +401,7 @@ io::sstream& CodeGenerator::generateSubpass(io::sstream& out, SubpassInfo subpas } CString subpassName = - SamplerInterfaceBlock::getUniformName(subpass.block.c_str(), subpass.name.c_str()); + SamplerInterfaceBlock::generateUniformName(subpass.block.c_str(), subpass.name.c_str()); char const* const typeName = "subpassInput"; // In our Vulkan backend, subpass inputs always live in descriptor set 2. (ignored for GLES) @@ -435,18 +430,13 @@ void CodeGenerator::fixupExternalSamplers( // been swapped during a previous optimization step for (auto const& info : infos) { if (info.type == SamplerType::SAMPLER_EXTERNAL) { - - CString uniformName = - SamplerInterfaceBlock::getUniformName( - sib.getName().c_str(), info.name.c_str()); - - auto name = std::string("sampler2D ") + uniformName.c_str(); + auto name = std::string("sampler2D ") + info.uniformName.c_str(); size_t index = shader.find(name); if (index != std::string::npos) { hasExternalSampler = true; auto newName = - std::string("samplerExternalOES ") + uniformName.c_str(); + std::string("samplerExternalOES ") + info.uniformName.c_str(); shader.replace(index, name.size(), newName); } } diff --git a/libs/filamat/src/shaders/MaterialInfo.h b/libs/filamat/src/shaders/MaterialInfo.h index f292b6395d..9b4ff31a7c 100644 --- a/libs/filamat/src/shaders/MaterialInfo.h +++ b/libs/filamat/src/shaders/MaterialInfo.h @@ -18,9 +18,12 @@ #define TNT_FILAMAT_MATERIALINFO_H #include + +#include "../SamplerBindingMap.h" + #include + #include -#include #include #include diff --git a/libs/filamat/src/shaders/ShaderGenerator.cpp b/libs/filamat/src/shaders/ShaderGenerator.cpp index a02d05dd6b..2b77032482 100644 --- a/libs/filamat/src/shaders/ShaderGenerator.cpp +++ b/libs/filamat/src/shaders/ShaderGenerator.cpp @@ -19,13 +19,13 @@ #include #include -#include #include #include #include "filamat/MaterialBuilder.h" #include "CodeGenerator.h" +#include "../SibGenerator.h" #include "../UibGenerator.h" #include