Skip to content

Commit 2926ef1

Browse files
committed
Eventually corrected pipelines deduplication
(ex06 now uses just 2 GL shaders)
1 parent aa64558 commit 2926ef1

File tree

4 files changed

+52
-12
lines changed

4 files changed

+52
-12
lines changed

examples_tests/06.MeshLoaders/main.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,36 @@
1313
using namespace irr;
1414
using namespace core;
1515

16+
static std::size_t pipeline_hash(asset::ICPURenderpassIndependentPipeline* _ppln)
17+
{
18+
constexpr size_t bytesToHash =
19+
asset::SVertexInputParams::serializedSize() +
20+
asset::SBlendParams::serializedSize() +
21+
asset::SRasterizationParams::serializedSize() +
22+
asset::SPrimitiveAssemblyParams::serializedSize() +
23+
sizeof(void*) * asset::ICPURenderpassIndependentPipeline::SHADER_STAGE_COUNT +//shaders
24+
sizeof(void*);//layout
25+
uint8_t mem[bytesToHash]{};
26+
uint32_t offset = 0u;
27+
_ppln->getVertexInputParams().serialize(mem + offset);
28+
offset += asset::SVertexInputParams::serializedSize();
29+
_ppln->getBlendParams().serialize(mem + offset);
30+
offset += asset::SBlendParams::serializedSize();
31+
_ppln->getRasterizationParams().serialize(mem + offset);
32+
offset += sizeof(asset::SRasterizationParams);
33+
_ppln->getPrimitiveAssemblyParams().serialize(mem + offset);
34+
offset += sizeof(asset::SPrimitiveAssemblyParams);
35+
const asset::ICPUSpecializedShader** shaders = reinterpret_cast<const asset::ICPUSpecializedShader**>(mem + offset);
36+
for (uint32_t i = 0u; i < asset::ICPURenderpassIndependentPipeline::SHADER_STAGE_COUNT; ++i)
37+
shaders[i] = _ppln->getShaderAtIndex(i);
38+
offset += asset::ICPURenderpassIndependentPipeline::SHADER_STAGE_COUNT * sizeof(void*);
39+
reinterpret_cast<const asset::ICPUPipelineLayout**>(mem + offset)[0] = _ppln->getLayout();
40+
41+
const std::size_t hs = std::hash<std::string_view>{}(std::string_view(reinterpret_cast<const char*>(mem), bytesToHash));
42+
43+
return hs;
44+
}
45+
1646
int main()
1747
{
1848
// create device with full flexibility over creation parameters

include/irr/video/IGPUObjectFromAssetConverter.h

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -217,9 +217,9 @@ class CAssetPreservingGPUObjectFromAssetConverter : public IGPUObjectFromAssetCo
217217

218218
// need to specialize outside because of GCC
219219
template<>
220-
struct IGPUObjectFromAssetConverter::Hash<asset::ICPURenderpassIndependentPipeline>
220+
struct IGPUObjectFromAssetConverter::Hash<const asset::ICPURenderpassIndependentPipeline>
221221
{
222-
inline std::size_t operator()(asset::ICPURenderpassIndependentPipeline* _ppln) const
222+
inline std::size_t operator()(const asset::ICPURenderpassIndependentPipeline* _ppln) const
223223
{
224224
constexpr size_t bytesToHash =
225225
asset::SVertexInputParams::serializedSize()+
@@ -250,9 +250,9 @@ struct IGPUObjectFromAssetConverter::Hash<asset::ICPURenderpassIndependentPipeli
250250
}
251251
};
252252
template<>
253-
struct IGPUObjectFromAssetConverter::Hash<asset::ICPUComputePipeline>
253+
struct IGPUObjectFromAssetConverter::Hash<const asset::ICPUComputePipeline>
254254
{
255-
inline std::size_t operator()(asset::ICPUComputePipeline* _ppln) const
255+
inline std::size_t operator()(const asset::ICPUComputePipeline* _ppln) const
256256
{
257257
constexpr size_t bytesToHash =
258258
sizeof(void*)+//shader
@@ -269,16 +269,16 @@ struct IGPUObjectFromAssetConverter::Hash<asset::ICPUComputePipeline>
269269
};
270270

271271
template<>
272-
struct IGPUObjectFromAssetConverter::KeyEqual<asset::ICPURenderpassIndependentPipeline>
272+
struct IGPUObjectFromAssetConverter::KeyEqual<const asset::ICPURenderpassIndependentPipeline>
273273
{
274274
//equality depends on hash only
275-
bool operator()(asset::ICPURenderpassIndependentPipeline* lhs, asset::ICPURenderpassIndependentPipeline* rhs) const { return true; }
275+
bool operator()(const asset::ICPURenderpassIndependentPipeline* lhs, const asset::ICPURenderpassIndependentPipeline* rhs) const { return true; }
276276
};
277277
template<>
278-
struct IGPUObjectFromAssetConverter::KeyEqual<asset::ICPUComputePipeline>
278+
struct IGPUObjectFromAssetConverter::KeyEqual<const asset::ICPUComputePipeline>
279279
{
280280
//equality depends on hash only
281-
bool operator()(asset::ICPUComputePipeline* lhs, asset::ICPUComputePipeline* rhs) const { return true; }
281+
bool operator()(const asset::ICPUComputePipeline* lhs, const asset::ICPUComputePipeline* rhs) const { return true; }
282282
};
283283

284284

src/irr/asset/CGraphicsPipelineLoaderMTL.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -194,8 +194,13 @@ bool CGraphicsPipelineLoaderMTL::isALoadableFileFormat(io::IReadFile* _file) con
194194
}
195195

196196

197-
core::smart_refctd_ptr<ICPUPipelineLayout> CGraphicsPipelineLoaderMTL::makePipelineLayoutFromMtl(const SMtl& _mtl, bool _noDS3)
197+
core::smart_refctd_ptr<ICPUPipelineLayout> CGraphicsPipelineLoaderMTL::makePipelineLayoutFromMtl(SContext& _ctx, const SMtl& _mtl, bool _noDS3)
198198
{
199+
const auto cacheKey = _ctx.layoutCacheKey(_mtl.clamp, _noDS3);
200+
201+
if (auto found = _ctx.layoutCache.find(cacheKey); found != _ctx.layoutCache.end())
202+
return found->second;
203+
199204
//assumes all supported textures are always present
200205
//since vulkan doesnt support bindings with no/null descriptor, absent textures will be filled with dummy 2D texture (while creating desc set)
201206
auto bindings = core::make_refctd_dynamic_array<core::smart_refctd_dynamic_array<ICPUDescriptorSetLayout::SBinding>>(static_cast<size_t>(CMTLPipelineMetadata::EMP_REFL_POSX)+1ull);
@@ -229,6 +234,8 @@ core::smart_refctd_ptr<ICPUPipelineLayout> CGraphicsPipelineLoaderMTL::makePipel
229234
//ds with textures for material goes to set=3
230235
auto layout = core::make_smart_refctd_ptr<ICPUPipelineLayout>(&pcRng, &pcRng+1, nullptr, std::move(ds1layout), nullptr, std::move(ds3Layout));
231236

237+
_ctx.layoutCache.insert({ cacheKey, layout });
238+
232239
return layout;
233240
}
234241

@@ -295,7 +302,7 @@ SAssetBundle CGraphicsPipelineLoaderMTL::loadAsset(io::IReadFile* _file, const I
295302
vtxParams.attributes[NORMAL].format = EF_A2B10G10R10_SNORM_PACK32;
296303
vtxParams.attributes[NORMAL].relativeOffset = 20u;
297304

298-
auto layout = makePipelineLayoutFromMtl(materials[i], true);
305+
auto layout = makePipelineLayoutFromMtl(ctx, materials[i], true);
299306
auto shaders = getShaders(false);
300307

301308
constexpr size_t DS1_METADATA_ENTRY_CNT = 3ull;
@@ -330,7 +337,7 @@ SAssetBundle CGraphicsPipelineLoaderMTL::loadAsset(io::IReadFile* _file, const I
330337
vtxParams.attributes[UV].format = EF_R32G32_SFLOAT;
331338
vtxParams.attributes[UV].relativeOffset = 12u;
332339

333-
layout = makePipelineLayoutFromMtl(materials[i], false);
340+
layout = makePipelineLayoutFromMtl(ctx, materials[i], false);
334341
shaders = getShaders(true);
335342

336343
core::smart_refctd_ptr<ICPUDescriptorSet> ds3;

src/irr/asset/CGraphicsPipelineLoaderMTL.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ namespace asset
3030
IAssetLoader::SAssetLoadContext inner;
3131
uint32_t topHierarchyLevel;
3232
IAssetLoader::IAssetLoaderOverride* loaderOverride;
33+
34+
static inline uint32_t layoutCacheKey(uint32_t clamps, bool no_ds3) { return clamps | (static_cast<uint32_t>(no_ds3) << 31); }
35+
core::unordered_map<uint32_t, core::smart_refctd_ptr<ICPUPipelineLayout>> layoutCache;
3336
};
3437

3538
public:
@@ -50,7 +53,7 @@ namespace asset
5053
asset::SAssetBundle loadAsset(io::IReadFile* _file, const asset::IAssetLoader::SAssetLoadParams& _params, asset::IAssetLoader::IAssetLoaderOverride* _override = nullptr, uint32_t _hierarchyLevel = 0u) override;
5154

5255
private:
53-
core::smart_refctd_ptr<ICPUPipelineLayout> makePipelineLayoutFromMtl(const SMtl& _mtl, bool _noDS3);
56+
core::smart_refctd_ptr<ICPUPipelineLayout> makePipelineLayoutFromMtl(SContext& ctx, const SMtl& _mtl, bool _noDS3);
5457
core::vector<SMtl> readMaterials(io::IReadFile* _file) const;
5558
const char* readTexture(const char* _bufPtr, const char* const _bufEnd, SMtl* _currMaterial, const char* _mapType) const;
5659

0 commit comments

Comments
 (0)