Skip to content

Commit f24ddec

Browse files
committed
Cache STL pipeline, adjust to changes
1 parent 4a9769c commit f24ddec

File tree

4 files changed

+122
-106
lines changed

4 files changed

+122
-106
lines changed

examples_tests/27.LoaderFixes/main.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ int main()
118118
{
119119
size_t neededDS1UboSize = 0ull;
120120
{
121-
for (const auto& shaderInputs : pipelineMetadata->getRequiredShaderInputs())
121+
for (const auto& shaderInputs : pipelineMetadata->m_inputSemantics)
122122
if (shaderInputs.descriptorSection.type == asset::IRenderpassIndependentPipelineMetadata::ShaderInput::ET_UNIFORM_BUFFER && shaderInputs.descriptorSection.uniformBufferObject.set == 1u && shaderInputs.descriptorSection.uniformBufferObject.binding == ds1UboBinding)
123123
neededDS1UboSize = std::max<size_t>(neededDS1UboSize, shaderInputs.descriptorSection.uniformBufferObject.relByteoffset + shaderInputs.descriptorSection.uniformBufferObject.bytesize);
124124
}
@@ -189,7 +189,7 @@ int main()
189189
core::matrix4SIMD mvp = core::concatenateBFollowedByA(viewProjection, modelMatrix);
190190

191191
core::vector<uint8_t> uboData(gpuubo->getSize());
192-
for (const auto& shaderInputs : pipelineMetadata->getRequiredShaderInputs())
192+
for (const auto& shaderInputs : pipelineMetadata->m_inputSemantics)
193193
{
194194
if (shaderInputs.descriptorSection.type == asset::IRenderpassIndependentPipelineMetadata::ShaderInput::ET_UNIFORM_BUFFER && shaderInputs.descriptorSection.uniformBufferObject.set == 1u && shaderInputs.descriptorSection.uniformBufferObject.binding == ds1UboBinding)
195195
{

src/nbl/asset/interchange/CPLYMeshFileLoader.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,7 @@ asset::SAssetBundle CPLYMeshFileLoader::loadAsset(io::IReadFile* _file, const as
298298
}
299299

300300
constexpr uint32_t WHAT_IS_THE_HASH_SUPPOSED_TO_BE = 69u; // TODO: @Crisspl / @Anastazluk figure it out!
301+
301302
auto meta = core::make_smart_refctd_ptr<CPLYMetadata>(std::move(ctx.hashes4pplns),core::smart_refctd_ptr(m_basicViewParamsSemantics));
302303
{
303304
uint32_t offset = 0u;

src/nbl/asset/interchange/CSTLMeshFileLoader.cpp

Lines changed: 109 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,105 @@ constexpr auto COLOR_ATTRIBUTE = 1;
2424
constexpr auto UV_ATTRIBUTE = 2;
2525
constexpr auto NORMAL_ATTRIBUTE = 3;
2626

27+
CSTLMeshFileLoader::CSTLMeshFileLoader(asset::IAssetManager* _m_assetMgr)
28+
: IRenderpassIndependentPipelineLoader(_m_assetMgr), m_assetMgr(_m_assetMgr)
29+
{
30+
initialize();
31+
IRenderpassIndependentPipelineLoader::initialize();
32+
}
33+
34+
void CSTLMeshFileLoader::initialize()
35+
{
36+
auto precomputeAndCachePipeline = [&](bool withColorAttribute)
37+
{
38+
auto getShaderDefaultPaths = [&]() -> std::pair<std::string_view, std::string_view>
39+
{
40+
if (withColorAttribute)
41+
return std::make_pair("nbl/builtin/material/debug/vertex_color/specialized_shader.vert", "nbl/builtin/material/debug/vertex_color/specialized_shader.frag");
42+
else
43+
return std::make_pair("nbl/builtin/material/debug/vertex_normal/specialized_shader.vert", "nbl/builtin/material/debug/vertex_normal/specialized_shader.frag");
44+
};
45+
46+
auto defaultOverride = IAssetLoaderOverride(m_assetMgr);
47+
const std::string pipelineCacheHash = getPipelineCacheKey(withColorAttribute).data();
48+
const uint32_t _hierarchyLevel = 0;
49+
const IAssetLoader::SAssetLoadContext fakeContext(IAssetLoader::SAssetLoadParams{}, nullptr);
50+
51+
const asset::IAsset::E_TYPE types[]{ asset::IAsset::ET_RENDERPASS_INDEPENDENT_PIPELINE, (asset::IAsset::E_TYPE)0u };
52+
auto pipelineBundle = defaultOverride.findCachedAsset(pipelineCacheHash, types, fakeContext, _hierarchyLevel + ICPURenderpassIndependentPipeline::DESC_SET_HIERARCHYLEVELS_BELOW);
53+
if (pipelineBundle.getContents().empty())
54+
{
55+
auto mbVertexShader = core::smart_refctd_ptr<ICPUSpecializedShader>();
56+
auto mbFragmentShader = core::smart_refctd_ptr<ICPUSpecializedShader>();
57+
{
58+
const IAsset::E_TYPE types[]{ IAsset::E_TYPE::ET_SPECIALIZED_SHADER, static_cast<IAsset::E_TYPE>(0u) };
59+
const auto shaderPaths = getShaderDefaultPaths();
60+
61+
auto vertexShaderBundle = m_assetMgr->findAssets(shaderPaths.first.data(), types);
62+
auto fragmentShaderBundle = m_assetMgr->findAssets(shaderPaths.second.data(), types);
63+
64+
mbVertexShader = core::smart_refctd_ptr_static_cast<ICPUSpecializedShader>(vertexShaderBundle->begin()->getContents().begin()[0]);
65+
mbFragmentShader = core::smart_refctd_ptr_static_cast<ICPUSpecializedShader>(fragmentShaderBundle->begin()->getContents().begin()[0]);
66+
}
67+
68+
auto defaultOverride = IAssetLoaderOverride(m_assetMgr);
69+
70+
const IAssetLoader::SAssetLoadContext fakeContext(IAssetLoader::SAssetLoadParams{}, nullptr);
71+
auto mbBundlePipelineLayout = defaultOverride.findDefaultAsset<ICPUPipelineLayout>("nbl/builtin/pipeline_layout/loader/STL", fakeContext, _hierarchyLevel + ICPURenderpassIndependentPipeline::PIPELINE_LAYOUT_HIERARCHYLEVELS_BELOW);
72+
auto mbPipelineLayout = mbBundlePipelineLayout.first;
73+
74+
auto const positionFormatByteSize = getTexelOrBlockBytesize(EF_R32G32B32_SFLOAT);
75+
auto const colorFormatByteSize = withColorAttribute ? getTexelOrBlockBytesize(EF_B8G8R8A8_UNORM) : 0;
76+
auto const normalFormatByteSize = getTexelOrBlockBytesize(EF_A2B10G10R10_SNORM_PACK32);
77+
78+
SVertexInputParams mbInputParams;
79+
const auto stride = positionFormatByteSize + colorFormatByteSize + normalFormatByteSize;
80+
mbInputParams.enabledBindingFlags |= core::createBitmask({ 0 });
81+
mbInputParams.enabledAttribFlags |= core::createBitmask({ POSITION_ATTRIBUTE, NORMAL_ATTRIBUTE, withColorAttribute ? COLOR_ATTRIBUTE : 0 });
82+
mbInputParams.bindings[0] = { stride, EVIR_PER_VERTEX };
83+
84+
mbInputParams.attributes[POSITION_ATTRIBUTE].format = EF_R32G32B32_SFLOAT;
85+
mbInputParams.attributes[POSITION_ATTRIBUTE].relativeOffset = 0;
86+
mbInputParams.attributes[POSITION_ATTRIBUTE].binding = 0;
87+
88+
if (withColorAttribute)
89+
{
90+
mbInputParams.attributes[COLOR_ATTRIBUTE].format = EF_R32G32B32_SFLOAT;
91+
mbInputParams.attributes[COLOR_ATTRIBUTE].relativeOffset = positionFormatByteSize;
92+
mbInputParams.attributes[COLOR_ATTRIBUTE].binding = 0;
93+
}
94+
95+
mbInputParams.attributes[NORMAL_ATTRIBUTE].format = EF_R32G32B32_SFLOAT;
96+
mbInputParams.attributes[NORMAL_ATTRIBUTE].relativeOffset = positionFormatByteSize + colorFormatByteSize;
97+
mbInputParams.attributes[NORMAL_ATTRIBUTE].binding = 0;
98+
99+
SBlendParams blendParams;
100+
SPrimitiveAssemblyParams primitiveAssemblyParams;
101+
primitiveAssemblyParams.primitiveType = E_PRIMITIVE_TOPOLOGY::EPT_TRIANGLE_LIST;
102+
103+
SRasterizationParams rastarizationParmas;
104+
105+
auto mbPipeline = core::make_smart_refctd_ptr<ICPURenderpassIndependentPipeline>(std::move(mbPipelineLayout), nullptr, nullptr, mbInputParams, blendParams, primitiveAssemblyParams, rastarizationParmas); // TODO: @Crisspl/@Anastazluk pipeline should also be builtin because no need to customize the metadata anymore
106+
{
107+
mbPipeline->setShaderAtIndex(ICPURenderpassIndependentPipeline::ESSI_VERTEX_SHADER_IX, mbVertexShader.get());
108+
mbPipeline->setShaderAtIndex(ICPURenderpassIndependentPipeline::ESSI_FRAGMENT_SHADER_IX, mbFragmentShader.get());
109+
}
110+
111+
asset::SAssetBundle newPipelineBundle(nullptr, {core::smart_refctd_ptr<asset::ICPURenderpassIndependentPipeline>(mbPipeline)});
112+
defaultOverride.insertAssetIntoCache(newPipelineBundle, pipelineCacheHash, fakeContext, _hierarchyLevel + ICPURenderpassIndependentPipeline::DESC_SET_HIERARCHYLEVELS_BELOW);
113+
}
114+
else
115+
return;
116+
};
117+
118+
/*
119+
Pipeline with color and no-coolr attribute is cached
120+
*/
121+
122+
precomputeAndCachePipeline(true);
123+
precomputeAndCachePipeline(false);
124+
}
125+
27126
SAssetBundle CSTLMeshFileLoader::loadAsset(IReadFile* _file, const IAssetLoader::SAssetLoadParams& _params, IAssetLoader::IAssetLoaderOverride* _override, uint32_t _hierarchyLevel)
28127
{
29128
if (_params.meshManipulatorOverride == nullptr)
@@ -166,119 +265,27 @@ SAssetBundle CSTLMeshFileLoader::loadAsset(IReadFile* _file, const IAssetLoader:
166265
memcpy(ptr + 16, colors.data() + i / 3, 4);
167266
}
168267

169-
// TODO: @Anastazluk PRECOMPUTE THE ENTIRE PIPELINE (since metadata is now free to change for every time the same handle gets returned)
170-
auto getShaderDefaultPaths = [&]() -> std::pair<std::string_view, std::string_view>
171-
{
172-
if (hasColor)
173-
return std::make_pair("nbl/builtin/material/debug/vertex_color/specialized_shader.vert", "nbl/builtin/material/debug/vertex_color/specialized_shader.frag");
174-
else
175-
return std::make_pair("nbl/builtin/material/debug/vertex_normal/specialized_shader.vert", "nbl/builtin/material/debug/vertex_normal/specialized_shader.frag");
176-
};
177-
auto mbVertexShader = core::smart_refctd_ptr<ICPUSpecializedShader>();
178-
auto mbFragmentShader = core::smart_refctd_ptr<ICPUSpecializedShader>();
179-
{
180-
const IAsset::E_TYPE types[]{ IAsset::E_TYPE::ET_SPECIALIZED_SHADER, static_cast<IAsset::E_TYPE>(0u) };
181-
const auto shaderPaths = getShaderDefaultPaths();
182-
183-
auto vertexShaderBundle = m_assetMgr->findAssets(shaderPaths.first.data(), types);
184-
auto fragmentShaderBundle = m_assetMgr->findAssets(shaderPaths.second.data(), types);
185-
186-
mbVertexShader = core::smart_refctd_ptr_static_cast<ICPUSpecializedShader>(vertexShaderBundle->begin()->getContents().begin()[0]);
187-
mbFragmentShader = core::smart_refctd_ptr_static_cast<ICPUSpecializedShader>(fragmentShaderBundle->begin()->getContents().begin()[0]);
188-
}
189-
190268
const IAssetLoader::SAssetLoadContext fakeContext(IAssetLoader::SAssetLoadParams{}, nullptr);
191-
auto mbBundlePipelineLayout = _override->findDefaultAsset<ICPUPipelineLayout>("nbl/builtin/pipeline_layout/loader/STL", fakeContext, _hierarchyLevel+ICPURenderpassIndependentPipeline::PIPELINE_LAYOUT_HIERARCHYLEVELS_BELOW);
192-
auto mbPipelineLayout = mbBundlePipelineLayout.first;
193-
194-
constexpr size_t DS1_METADATA_ENTRY_CNT = 3ull;
195-
196-
// TODO: @Anastazluk use `m_basicViewParamsSemantics` from IRenderpassIndependentPipelineLoader
197-
core::smart_refctd_dynamic_array<IRenderpassIndependentPipelineMetadata::ShaderInputSemantic> shaderInputsMetadata = core::make_refctd_dynamic_array<decltype(shaderInputsMetadata)>(DS1_METADATA_ENTRY_CNT);
269+
const asset::IAsset::E_TYPE types[]{ asset::IAsset::ET_RENDERPASS_INDEPENDENT_PIPELINE, (asset::IAsset::E_TYPE)0u };
270+
auto pipelineBundle = _override->findCachedAsset(getPipelineCacheKey(hasColor).data(), types, fakeContext, _hierarchyLevel + ICPURenderpassIndependentPipeline::DESC_SET_HIERARCHYLEVELS_BELOW);
198271
{
199-
ICPUDescriptorSetLayout* ds1layout = mbPipelineLayout->getDescriptorSetLayout(1u); // this metadata should probably go into pipeline layout's asset bundle (@Crisspl TODO: review)
200-
201-
// TODO: I will move all below to IAssetManager and put it into Pipeline Layout's metadata
202-
203-
constexpr IRenderpassIndependentPipelineMetadata::E_COMMON_SHADER_INPUT types[DS1_METADATA_ENTRY_CNT] =
204-
{
205-
IRenderpassIndependentPipelineMetadata::ECSI_WORLD_VIEW_PROJ,
206-
IRenderpassIndependentPipelineMetadata::ECSI_WORLD_VIEW,
207-
IRenderpassIndependentPipelineMetadata::ECSI_WORLD_VIEW_INVERSE_TRANSPOSE
208-
};
209-
constexpr uint32_t sizes[DS1_METADATA_ENTRY_CNT] =
210-
{
211-
sizeof(SBasicViewParameters::MVP),
212-
sizeof(SBasicViewParameters::MV),
213-
sizeof(SBasicViewParameters::NormalMat)
214-
};
215-
constexpr uint32_t relOffsets[DS1_METADATA_ENTRY_CNT] =
216-
{
217-
offsetof(SBasicViewParameters,MVP),
218-
offsetof(SBasicViewParameters,MV),
219-
offsetof(SBasicViewParameters,NormalMat)
220-
};
221-
for (uint32_t i = 0u; i < DS1_METADATA_ENTRY_CNT; ++i)
222-
{
223-
auto& semantic = (shaderInputsMetadata->end() - i - 1u)[0];
224-
semantic.type = types[i];
225-
semantic.descriptorSection.type = IRenderpassIndependentPipelineMetadata::ShaderInput::ET_UNIFORM_BUFFER;
226-
semantic.descriptorSection.uniformBufferObject.binding = ds1layout->getBindings().begin()[0].binding;
227-
semantic.descriptorSection.uniformBufferObject.set = 1u;
228-
semantic.descriptorSection.uniformBufferObject.relByteoffset = relOffsets[i];
229-
semantic.descriptorSection.uniformBufferObject.bytesize = sizes[i];
230-
semantic.descriptorSection.shaderAccessFlags = ICPUSpecializedShader::ESS_VERTEX;
231-
}
272+
bool status = !pipelineBundle.getContents().empty();
273+
assert(status);
232274
}
233275

234-
auto const positionFormatByteSize = getTexelOrBlockBytesize(EF_R32G32B32_SFLOAT);
235-
auto const colorFormatByteSize = hasColor ? getTexelOrBlockBytesize(EF_B8G8R8A8_UNORM) : 0;
236-
auto const normalFormatByteSize = getTexelOrBlockBytesize(EF_A2B10G10R10_SNORM_PACK32);
237-
238-
SVertexInputParams mbInputParams;
239-
const auto stride = positionFormatByteSize + colorFormatByteSize + normalFormatByteSize;
240-
mbInputParams.enabledBindingFlags |= core::createBitmask({0});
241-
mbInputParams.enabledAttribFlags |= core::createBitmask({POSITION_ATTRIBUTE, NORMAL_ATTRIBUTE, hasColor ? COLOR_ATTRIBUTE : 0});
242-
mbInputParams.bindings[0] = { stride, EVIR_PER_VERTEX };
243-
244-
mbInputParams.attributes[POSITION_ATTRIBUTE].format = EF_R32G32B32_SFLOAT;
245-
mbInputParams.attributes[POSITION_ATTRIBUTE].relativeOffset = 0;
246-
mbInputParams.attributes[POSITION_ATTRIBUTE].binding = 0;
247-
248-
if (hasColor)
249-
{
250-
mbInputParams.attributes[COLOR_ATTRIBUTE].format = EF_R32G32B32_SFLOAT;
251-
mbInputParams.attributes[COLOR_ATTRIBUTE].relativeOffset = positionFormatByteSize;
252-
mbInputParams.attributes[COLOR_ATTRIBUTE].binding = 0;
253-
}
276+
auto mbPipeline = core::smart_refctd_ptr_static_cast<asset::ICPURenderpassIndependentPipeline>(pipelineBundle.getContents().begin()[0]);
254277

255-
mbInputParams.attributes[NORMAL_ATTRIBUTE].format = EF_R32G32B32_SFLOAT;
256-
mbInputParams.attributes[NORMAL_ATTRIBUTE].relativeOffset = positionFormatByteSize + colorFormatByteSize;
257-
mbInputParams.attributes[NORMAL_ATTRIBUTE].binding = 0;
258-
259-
SBlendParams blendParams;
260-
SPrimitiveAssemblyParams primitiveAssemblyParams;
261-
primitiveAssemblyParams.primitiveType = E_PRIMITIVE_TOPOLOGY::EPT_TRIANGLE_LIST;
262-
263-
SRasterizationParams rastarizationParmas;
264-
265-
auto mbPipeline = core::make_smart_refctd_ptr<ICPURenderpassIndependentPipeline>(std::move(mbPipelineLayout), nullptr, nullptr, mbInputParams, blendParams, primitiveAssemblyParams, rastarizationParmas); // TODO: @Crisspl/@Anastazluk pipeline should also be builtin because no need to customize the metadata anymore
266-
{
267-
mbPipeline->setShaderAtIndex(ICPURenderpassIndependentPipeline::ESSI_VERTEX_SHADER_IX, mbVertexShader.get());
268-
mbPipeline->setShaderAtIndex(ICPURenderpassIndependentPipeline::ESSI_FRAGMENT_SHADER_IX, mbFragmentShader.get());
269-
meshbuffer->setVertexBufferBinding({ 0ul, vertexBuf }, 0);
270-
}
271-
272-
auto meta = core::make_smart_refctd_ptr<CSTLMetadata>(1u);
273-
meta->placeMeta(0u,mbPipeline.get(),std::move(shaderInputsMetadata));
278+
auto meta = core::make_smart_refctd_ptr<CSTLMetadata>(1u, std::move(m_basicViewParamsSemantics));
279+
meta->placeMeta(0u, mbPipeline.get());
274280

275281
meshbuffer->setPipeline(std::move(mbPipeline));
276282
meshbuffer->setIndexCount(positions.size());
277283
meshbuffer->setIndexType(asset::EIT_UNKNOWN);
278284

285+
meshbuffer->setVertexBufferBinding({ 0ul, vertexBuf }, 0);
279286
mesh->getMeshBufferVector().emplace_back(std::move(meshbuffer));
280-
281-
return SAssetBundle(std::move(meta),{ std::move(mesh) });
287+
288+
return SAssetBundle(std::move(meta), { std::move(mesh) });
282289
}
283290

284291

src/nbl/asset/interchange/CSTLMeshFileLoader.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,11 @@ namespace asset
1515
{
1616

1717
//! Meshloader capable of loading STL meshes.
18-
class CSTLMeshFileLoader final : public IAssetLoader
18+
class CSTLMeshFileLoader final : public IAssetLoader, public IRenderpassIndependentPipelineLoader
1919
{
2020
public:
2121

22-
CSTLMeshFileLoader(asset::IAssetManager* _m_assetMgr) : m_assetMgr(_m_assetMgr) {}
22+
CSTLMeshFileLoader(asset::IAssetManager* _m_assetMgr);
2323

2424
asset::SAssetBundle loadAsset(io::IReadFile* _file, const IAssetLoader::SAssetLoadParams& _params, IAssetLoader::IAssetLoaderOverride* _override = nullptr, uint32_t _hierarchyLevel = 0u) override;
2525

@@ -35,6 +35,14 @@ class CSTLMeshFileLoader final : public IAssetLoader
3535

3636
private:
3737

38+
/*
39+
Precompute STL pipeline
40+
*/
41+
42+
void initialize();
43+
44+
const std::string_view getPipelineCacheKey(bool withColorAttribute) { return withColorAttribute ? "nbl/builtin/pipeline/loader/STL/color_attribute" : "nbl/builtin/pipeline/loader/STL/no_color_attribute"; }
45+
3846
// skips to the first non-space character available
3947
void goNextWord(io::IReadFile* file) const;
4048
// returns the next word

0 commit comments

Comments
 (0)