Skip to content

Commit 4d73f2f

Browse files
committed
New asset restore system (without restore-whole-bundle option yet though) + some doubts/suggestions in comments
1 parent f27e2d9 commit 4d73f2f

19 files changed

+228
-108
lines changed

include/nbl/asset/IAsset.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,15 @@ class IAsset : virtual public core::IReferenceCounted
204204

205205
virtual bool canBeRestoredFrom(const IAsset* _other) const = 0;
206206

207+
// returns if `this` is dummy or any of its dependencies up to `_levelsBelow` levels below
208+
bool isAnyDependencyDummy(uint32_t _levelsBelow = ~0u) const
209+
{
210+
if (isADummyObjectForCache())
211+
return true;
212+
213+
return _levelsBelow ? isAnyDependencyDummy_impl(_levelsBelow) : false;
214+
}
215+
207216
protected:
208217
inline static void restoreFromDummy_impl_call(IAsset* _this_child, IAsset* _other_child, uint32_t _levelsBelow)
209218
{
@@ -212,6 +221,9 @@ class IAsset : virtual public core::IReferenceCounted
212221

213222
virtual void restoreFromDummy_impl(IAsset* _other, uint32_t _levelsBelow) = 0;
214223

224+
// returns if any of `this`'s up to `_levelsBelow` levels below is dummy
225+
virtual bool isAnyDependencyDummy_impl(uint32_t _levelsBelow) const { return false; }
226+
215227
inline void clone_common(IAsset* _clone) const
216228
{
217229
assert(!isDummyObjectForCacheAliasing);

include/nbl/asset/IAssetManager.h

Lines changed: 54 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -203,28 +203,37 @@ class IAssetManager : public core::IReferenceCounted, public core::QuitSignallin
203203
*/
204204
SAssetBundle getAssetInHierarchy(io::IReadFile* _file, const std::string& _supposedFilename, const IAssetLoader::SAssetLoadParams& _params, uint32_t _hierarchyLevel, IAssetLoader::IAssetLoaderOverride* _override)
205205
{
206+
const uint32_t restoreLevels = (_hierarchyLevel >= _params.restoreLevels) ? 0u : (_params.restoreLevels - _hierarchyLevel);
207+
206208
IAssetLoader::SAssetLoadParams params(_params);
207209
if (params.meshManipulatorOverride == nullptr)
208210
{
209211
params.meshManipulatorOverride = m_meshManipulator.get();
210212
}
213+
if (restoreLevels)
214+
{
215+
using flags_t = std::underlying_type_t<IAssetLoader::E_CACHING_FLAGS>;
216+
flags_t mask = ~static_cast<flags_t>(0);
217+
mask = core::bitfieldInsert<flags_t>(mask, IAssetLoader::ECF_DONT_CACHE_REFERENCES, 2u*_hierarchyLevel, 2u*restoreLevels);
218+
params.cacheFlags = static_cast<IAssetLoader::E_CACHING_FLAGS>(params.cacheFlags & mask);
219+
}
211220

212221
IAssetLoader::SAssetLoadContext ctx{params, _file};
213222

214223
std::string filename = _file ? _file->getFileName().c_str() : _supposedFilename;
215-
io::IReadFile* file = _override->getLoadFile(_file, filename, ctx, _hierarchyLevel);
224+
io::IReadFile* file = _override->getLoadFile(_file, filename, ctx, _hierarchyLevel); // WARNING: mem-leak possibility: _override should return smart_ptr<IReadFile> (TODO, inspect this)
216225
filename = file ? file->getFileName().c_str() : _supposedFilename;
217226

218227
const uint64_t levelFlags = params.cacheFlags >> ((uint64_t)_hierarchyLevel * 2ull);
219228

220-
SAssetBundle asset;
229+
SAssetBundle bundle;
221230
if ((levelFlags & IAssetLoader::ECF_DUPLICATE_TOP_LEVEL) != IAssetLoader::ECF_DUPLICATE_TOP_LEVEL)
222231
{
223232
auto found = findAssets(filename);
224233
if (found->size())
225234
return _override->chooseRelevantFromFound(found->begin(), found->end(), ctx, _hierarchyLevel);
226-
else if (!(asset = _override->handleSearchFail(filename, ctx, _hierarchyLevel)).getContents().empty())
227-
return asset;
235+
else if (!(bundle = _override->handleSearchFail(filename, ctx, _hierarchyLevel)).getContents().empty())
236+
return bundle;
228237
}
229238

230239
// if at this point, and after looking for an asset in cache, file is still nullptr, then return nullptr
@@ -235,30 +244,61 @@ class IAssetManager : public core::IReferenceCounted, public core::QuitSignallin
235244
// loaders associated with the file's extension tryout
236245
for (auto& loader : capableLoadersRng)
237246
{
238-
if (loader.second->isALoadableFileFormat(file) && !(asset = loader.second->loadAsset(file, params, _override, _hierarchyLevel)).getContents().empty())
247+
if (loader.second->isALoadableFileFormat(file) && !(bundle = loader.second->loadAsset(file, params, _override, _hierarchyLevel)).getContents().empty())
239248
break;
240249
}
241-
for (auto loaderItr = std::begin(m_loaders.vector); asset.getContents().empty() && loaderItr != std::end(m_loaders.vector); ++loaderItr) // all loaders tryout
250+
for (auto loaderItr = std::begin(m_loaders.vector); bundle.getContents().empty() && loaderItr != std::end(m_loaders.vector); ++loaderItr) // all loaders tryout
242251
{
243-
if ((*loaderItr)->isALoadableFileFormat(file) && !(asset = (*loaderItr)->loadAsset(file, params, _override, _hierarchyLevel)).getContents().empty())
252+
if ((*loaderItr)->isALoadableFileFormat(file) && !(bundle = (*loaderItr)->loadAsset(file, params, _override, _hierarchyLevel)).getContents().empty())
244253
break;
245254
}
246255

247-
if (!asset.getContents().empty() &&
256+
if (!bundle.getContents().empty() &&
248257
((levelFlags & IAssetLoader::ECF_DONT_CACHE_TOP_LEVEL) != IAssetLoader::ECF_DONT_CACHE_TOP_LEVEL) &&
249258
((levelFlags & IAssetLoader::ECF_DUPLICATE_TOP_LEVEL) != IAssetLoader::ECF_DUPLICATE_TOP_LEVEL))
250259
{
251-
_override->insertAssetIntoCache(asset, filename, ctx, _hierarchyLevel);
260+
_override->insertAssetIntoCache(bundle, filename, ctx, _hierarchyLevel);
252261
}
253-
else if (asset.getContents().empty())
262+
else if (bundle.getContents().empty())
254263
{
255264
bool addToCache;
256-
asset = _override->handleLoadFail(addToCache, file, filename, filename, ctx, _hierarchyLevel);
257-
if (!asset.getContents().empty() && addToCache)
258-
_override->insertAssetIntoCache(asset, filename, ctx, _hierarchyLevel);
265+
bundle = _override->handleLoadFail(addToCache, file, filename, filename, ctx, _hierarchyLevel);
266+
if (!bundle.getContents().empty() && addToCache)
267+
_override->insertAssetIntoCache(bundle, filename, ctx, _hierarchyLevel);
268+
}
269+
270+
if (bundle.getContents().empty() /*|| none of req levels is dummy*/)
271+
return bundle;
272+
273+
if (restoreLevels)
274+
{
275+
auto reloadParams = _params;
276+
{
277+
using flags_t = std::underlying_type_t<IAssetLoader::E_CACHING_FLAGS>;
278+
constexpr uint32_t bitdepth = sizeof(flags_t)*8u;
279+
const flags_t zeroOutMask = (~static_cast<flags_t>(0)) >> (bitdepth - 2u*(restoreLevels + _hierarchyLevel));
280+
flags_t reloadFlags = reloadParams.cacheFlags;
281+
reloadFlags &= zeroOutMask; // make sure we never pointlessy reload levels above (_restoreLevels+_hierLevel) in reload pass
282+
// set flags for levels [_hierLevel,_hierLevel+_restoreLevels) to dont look into cache and dont put into cache
283+
reloadFlags = core::bitfieldInsert<flags_t>(reloadFlags, IAssetLoader::ECF_DUPLICATE_REFERENCES, _hierarchyLevel*2u, restoreLevels*2u);
284+
reloadParams.cacheFlags = static_cast<IAssetLoader::E_CACHING_FLAGS>(reloadFlags);
285+
286+
reloadParams.restoreLevels = 0u; // make sure it wont turn into infinite recursion
287+
reloadParams.reload = true; // TODO (consider): alternative to this flag: another method in override just to let user choose asset for restore
288+
}
289+
IAssetLoader::SAssetLoadContext ctx(params, file);
290+
auto asset = _override->chooseDefaultAsset(bundle, ctx);
291+
if (!asset->isAnyDependencyDummy(restoreLevels - 1u))
292+
return bundle;
293+
294+
auto reloadBundle = getAssetInHierarchy(_file, _supposedFilename, reloadParams, _hierarchyLevel, _override);
295+
296+
bool restoreSucceeded = _override->handleRestore(std::move(asset), bundle, reloadBundle, restoreLevels);
297+
if (!restoreSucceeded) // hm? return empty bundle if restore was requested, but did not succeeded? or just return the bundle? (TODO consider)
298+
return {};
259299
}
260300

261-
return asset;
301+
return bundle;
262302
}
263303
//TODO change name
264304
SAssetBundle getAssetInHierarchy(const std::string& _filePath, const IAssetLoader::SAssetLoadParams& _params, uint32_t _hierarchyLevel, IAssetLoader::IAssetLoaderOverride* _override)

include/nbl/asset/ICPUBufferView.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,11 @@ class ICPUBufferView : public IBufferView<ICPUBuffer>, public IAsset
9090
}
9191
}
9292

93+
bool isAnyDependencyDummy_impl(uint32_t _levelsBelow) const override
94+
{
95+
return m_buffer->isAnyDependencyDummy(_levelsBelow-1u);
96+
}
97+
9398
virtual ~ICPUBufferView() = default;
9499
};
95100

include/nbl/asset/ICPUComputePipeline.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,12 @@ class ICPUComputePipeline : public IComputePipeline<ICPUSpecializedShader, ICPUP
9696
}
9797
}
9898

99+
bool isAnyDependencyDummy_impl(uint32_t _levelsBelow) const override
100+
{
101+
--_levelsBelow;
102+
return m_shader->isAnyDependencyDummy(_levelsBelow) || m_layout->isAnyDependencyDummy(_levelsBelow);
103+
}
104+
99105
virtual ~ICPUComputePipeline() = default;
100106
};
101107

include/nbl/asset/ICPUDescriptorSet.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,38 @@ class ICPUDescriptorSet final : public IDescriptorSet<ICPUDescriptorSetLayout>,
238238
}
239239
}
240240

241+
bool isAnyDependencyDummy_impl(uint32_t _levelsBelow) const override
242+
{
243+
--_levelsBelow;
244+
if (m_layout->isAnyDependencyDummy(_levelsBelow))
245+
return true;
246+
for (auto it = m_descriptors->begin(); it != m_descriptors->end(); it++)
247+
{
248+
auto descriptor = it->desc.get();
249+
if (!descriptor)
250+
continue;
251+
252+
switch (descriptor->getTypeCategory())
253+
{
254+
case IDescriptor::EC_BUFFER:
255+
if (static_cast<ICPUBuffer*>(descriptor)->isAnyDependencyDummy(_levelsBelow))
256+
return true;
257+
break;
258+
case IDescriptor::EC_IMAGE:
259+
if (static_cast<ICPUImageView*>(descriptor)->isAnyDependencyDummy(_levelsBelow))
260+
return true;
261+
if (it->image.sampler && it->image.sampler->isAnyDependencyDummy(_levelsBelow))
262+
return true;
263+
break;
264+
case IDescriptor::EC_BUFFER_VIEW:
265+
if (static_cast<ICPUBufferView*>(descriptor)->isAnyDependencyDummy(_levelsBelow))
266+
return true;
267+
break;
268+
}
269+
}
270+
return false;
271+
}
272+
241273
virtual ~ICPUDescriptorSet() = default;
242274
};
243275

include/nbl/asset/ICPUDescriptorSetLayout.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,16 @@ class ICPUDescriptorSetLayout : public IDescriptorSetLayout<ICPUSampler>, public
106106
restoreFromDummy_impl_call((*m_samplers)[i].get(), (*other->m_samplers)[i].get(), _levelsBelow);
107107
}
108108

109+
bool isAnyDependencyDummy_impl(uint32_t _levelsBelow) const override
110+
{
111+
--_levelsBelow;
112+
if (m_samplers)
113+
for (uint32_t i = 0u; i < m_samplers->size(); ++i)
114+
if ((*m_samplers)[i]->isAnyDependencyDummy(_levelsBelow))
115+
return true;
116+
return false;
117+
}
118+
109119
virtual ~ICPUDescriptorSetLayout() = default;
110120
};
111121

include/nbl/asset/ICPUImage.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,12 @@ class ICPUImage final : public IImage, public IAsset
199199
restoreFromDummy_impl_call(buffer.get(), other->buffer.get(), _levelsBelow - 1u);
200200
}
201201

202+
bool isAnyDependencyDummy_impl(uint32_t _levelsBelow) const override
203+
{
204+
--_levelsBelow;
205+
return buffer->isAnyDependencyDummy(_levelsBelow);
206+
}
207+
202208
ICPUImage(SCreationParams&& _params) : IImage(std::move(_params))
203209
{
204210
}

include/nbl/asset/ICPUImageView.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,12 @@ class ICPUImageView final : public IImageView<ICPUImage>, public IAsset
9797
}
9898
}
9999

100+
bool isAnyDependencyDummy_impl(uint32_t _levelsBelow) const override
101+
{
102+
--_levelsBelow;
103+
return params.image->isAnyDependencyDummy(_levelsBelow);
104+
}
105+
100106
virtual ~ICPUImageView() = default;
101107
};
102108

include/nbl/asset/ICPUMesh.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,16 @@ class ICPUMesh final : public IMesh<ICPUMeshBuffer>, public BlobSerializable, pu
128128
}
129129
}
130130

131+
bool isAnyDependencyDummy_impl(uint32_t _levelsBelow) const override
132+
{
133+
--_levelsBelow;
134+
auto mbs = getMeshBuffers();
135+
for (auto mb : mbs)
136+
if (mb->isAnyDependencyDummy(_levelsBelow))
137+
return true;
138+
return false;
139+
}
140+
131141
core::vector<core::smart_refctd_ptr<ICPUMeshBuffer>> m_meshBuffers;
132142
};
133143

include/nbl/asset/ICPUMeshBuffer.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -616,6 +616,21 @@ class ICPUMeshBuffer : public IMeshBuffer<ICPUBuffer, ICPUDescriptorSet, ICPURen
616616
restoreFromDummy_impl_call(m_indexBufferBinding.buffer.get(), other->m_indexBufferBinding.buffer.get(), _levelsBelow);
617617
}
618618
}
619+
620+
bool isAnyDependencyDummy_impl(uint32_t _levelsBelow) const override
621+
{
622+
--_levelsBelow;
623+
if (m_pipeline && m_pipeline->isAnyDependencyDummy(_levelsBelow))
624+
return true;
625+
if (m_descriptorSet && m_descriptorSet->isAnyDependencyDummy(_levelsBelow))
626+
return true;
627+
628+
for (uint32_t i = 0u; i < MAX_ATTR_BUF_BINDING_COUNT; ++i)
629+
if (m_vertexBufferBindings[i].buffer && m_vertexBufferBindings[i].buffer->isAnyDependencyDummy(_levelsBelow))
630+
return true;
631+
632+
return (m_indexBufferBinding.buffer && m_indexBufferBinding.buffer->isAnyDependencyDummy(_levelsBelow));
633+
}
619634
};
620635

621636
}}

0 commit comments

Comments
 (0)