@@ -24,6 +24,105 @@ constexpr auto COLOR_ATTRIBUTE = 1;
24
24
constexpr auto UV_ATTRIBUTE = 2 ;
25
25
constexpr auto NORMAL_ATTRIBUTE = 3 ;
26
26
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
+
27
126
SAssetBundle CSTLMeshFileLoader::loadAsset (IReadFile* _file, const IAssetLoader::SAssetLoadParams& _params, IAssetLoader::IAssetLoaderOverride* _override, uint32_t _hierarchyLevel)
28
127
{
29
128
if (_params.meshManipulatorOverride == nullptr )
@@ -166,119 +265,27 @@ SAssetBundle CSTLMeshFileLoader::loadAsset(IReadFile* _file, const IAssetLoader:
166
265
memcpy (ptr + 16 , colors.data () + i / 3 , 4 );
167
266
}
168
267
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
-
190
268
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);
198
271
{
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);
232
274
}
233
275
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 ]);
254
277
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 ());
274
280
275
281
meshbuffer->setPipeline (std::move (mbPipeline));
276
282
meshbuffer->setIndexCount (positions.size ());
277
283
meshbuffer->setIndexType (asset::EIT_UNKNOWN);
278
284
285
+ meshbuffer->setVertexBufferBinding ({ 0ul , vertexBuf }, 0 );
279
286
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) });
282
289
}
283
290
284
291
0 commit comments