Vulkan Schnee 0.0.1
High-performance rendering engine
Loading...
Searching...
No Matches
AssetManager.cpp
Go to the documentation of this file.
2
15
19#include <plog/Log.h>
20#include <ranges>
21#include <type_traits>
22
23namespace EngineCore {
32
42
51
53 this->renderer = renderer;
54 }
55
57 texturePipeline.setRenderingDataManager(renderingDataManager);
58 modelAssetPipeline.setRenderingDataManager(renderingDataManager);
59 }
60
61 void AssetManager::loadEcsModel(const std::filesystem::path &path) {
62 TRACY_ZONE_SCOPED_NAMED("Loading Ecs mesh");
63
64 if (!modelAssetManager->exists(path))
65 {
66 modelAssetManager->add(path, new ModelAsset(path));
67 modelAssetPipeline.submitAsset(path);
68 }
69 }
70
72 {
73 auto data = meshAssetManager->getAsset( asset );
74 if (!data.has_value())
75 {
77 return nullptr;
78 }
79 return data.value();
80 }
81
82 void AssetManager::loadEcsTexture(const std::filesystem::path &path) {
83 TRACY_ZONE_SCOPED_NAMED("Loading texture data");
84 texturePipeline.submitAsset(path);
85 textureAssetManager->declare(path);
86 }
87
88 std::vector<const Mesh *> AssetManager::getAllMeshes() const {
89 std::vector<const Mesh *> allMeshes(meshAllocator.getUsedIndices().size());
90 uint32_t i = 0;
91 for (const std::optional<Mesh> &mesh: meshData) {
92 if (!mesh.has_value()) continue;
93 allMeshes[i] = &mesh.value();
94 i++;
95 }
96 return allMeshes;
97 }
98
100 uint32_t primCount = 0u;
101 for (const Mesh *mesh: getAllMeshes()) {
102 primCount += mesh->getPrimitives().size();
103 }
104 return primCount;
105 }
106
107 bool AssetManager::doesMeshAlreadyExist(const std::filesystem::path &meshPath) const {
108 return meshes.find(meshPath) != meshes.end();
109 }
110
112 PLOGI << "Loaded Mesh count: " << meshes.size();
113 PLOGI << "Loaded Texture count: " << textures.size();
114 }
115
117 meshOffsets.clear();
118
119 uint32_t sum = 0u;
120 for (std::optional<Mesh> &mesh: meshData) {
121 if (!mesh.has_value()) continue;
122 meshOffsets[&mesh.value()] = sum;
123 sum += mesh.value().getMeshletCount();
124 }
125 }
126
128 textures.clear();
129 meshes.clear();
130
131 meshAllocator.reset(0);
132 for (auto &mesh: meshData) {
133 if (mesh.has_value()) {
134 mesh->cleanup();
135 }
136 mesh.reset();
137 }
138 for (auto &texture: textureData) {
139 if (texture.has_value()) {
140 texture->cleanup();
141 }
142 texture.reset();
143 }
144
145 for (auto &val: materialStorageBuffers | std::views::values) {
146 val.destroy();
147 }
149 }
150
151 std::vector<VkDescriptorImageInfo> AssetManager::getTextureDescriptorInfos() const {
152 std::vector<VkDescriptorImageInfo> descriptorTextures;
153 for (auto &texture: textureData) {
154 if (!texture.has_value()) continue;
155 VkDescriptorImageInfo descriptorImageInfo;
156 descriptorImageInfo.sampler = texture.value().getVkImageSampler();
157 descriptorImageInfo.imageView = texture.value().getVkImageView();
158 descriptorImageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
159 descriptorTextures.push_back(descriptorImageInfo);
160 }
161 return descriptorTextures;
162 }
163
165 return shaders.size();
166 }
167
168 std::vector<MaterialShader *> AssetManager::getShaders() const {
169 return shaders;
170 }
171
173 return DIFFUSE_FLAT_COLOR;
174 }
175
176 MaterialShader *AssetManager::getShaderByName(const std::string &shaderName) {
177 PipelineNames name = materialNameFromString(shaderName);
178 return getShaderByName(name);
179 }
180
182 const auto it = shadersByName.find(shaderName);
183 if (it == shadersByName.end()) {
184 return nullptr;
185 }
186 return it->second;
187 }
188
189 std::vector<Texture *> AssetManager::getTexturesToUpload() {
191 }
192
193 uint32_t AssetManager::getMeshOffset(Mesh *mesh) const {
194 return meshOffsets.at(mesh);
195 }
196
198 uint32_t index = shaderAllocator.allocate();
199
200 shaderData[index] = std::move(shader);
201 MaterialShader *shaderPtr = &shaderData[index].value();
202 shaders.push_back(shaderPtr);
203 shaderOffsets[shaderPtr] = index;
204
205 shadersByName[materialName] = shaderPtr;
206 return shaderPtr;
207 }
208
210 uint32_t shaderIndex = shaderOffsets[shader];
211 shaderOffsets.erase(shader);
212
213 if (const auto it = std::ranges::find(shaders, shader); it != shaders.end()) {
214 shaders.erase(it);
215 }
216
217 shaderData[shaderIndex].reset();
218 }
219
223
224 std::vector<const MeshPrimitive *> AssetManager::getMeshPrimitivesFromMeshes(
225 const std::vector<const Mesh *> &meshes) const {
226 std::vector<const MeshPrimitive *> allPrimitives;
227
228 for (const Mesh *mesh: meshes) {
229 // Use your new "ByRef" getter to get a reference to the original vector
230 for (const MeshPrimitive &primitive: mesh->getPrimitivesByReference()) {
231 // Store the ADDRESS of the original primitive. No copy is made.
232 allPrimitives.push_back(&primitive);
233 }
234 }
235 return allPrimitives;
236 }
237
238 std::vector<MeshPrimitive *> AssetManager::getMeshPrimitivesFromMeshes(const std::vector<Mesh *> &meshes) {
239 std::vector<MeshPrimitive *> allPrimitives;
240
241 for (Mesh *mesh: meshes) {
242 // Use your new "ByRef" getter to get a reference to the original vector
243 for (MeshPrimitive &primitive: mesh->getPrimitivesByReference()) {
244 // Store the ADDRESS of the original primitive. No copy is made.
245 allPrimitives.push_back(&primitive);
246 }
247 }
248 return allPrimitives;
249 }
250
251 uint32_t AssetManager::getMeshletCount(const std::vector<const Mesh *> &meshes) const {
252 uint32_t meshletCount = 0;
253 uint32_t primitiveCount = 0;
254 for (const Mesh *mesh: meshes) {
255 for (const MeshPrimitive &primitive: mesh->getPrimitivesByReference()) {
256 uint32_t primMeshletCount = primitive.getMeshletsCount();
257 meshletCount += primMeshletCount;
258 primitiveCount++;
259 if (primMeshletCount == 0) {
260 PLOGW << "Primitive " << primitiveCount << " has 0 meshlets!";
261 }
262 }
263 }
264 PLOGI << "Total meshlet count: " << meshletCount << " from " << primitiveCount << " primitives";
265 return meshletCount;
266 }
267
271
275
277 {
278 TRACY_ZONE_SCOPED_NAMED("Unloading manager data");
279 materialAssetManager->clear();
280 meshAssetManager->clear();
281 modelAssetManager->clear();
282 textureAssetManager->clear();
283 }
284
286 {
287 return UnpackOptional(meshAssetManager->getAsset( asset ));
288 }
289
290 bool AssetManager::doesTextureAlreadyExist(const std::filesystem::path &path) {
291 TRACY_LOCK_GUARD(std::mutex, lock, textureMutex);
292 return textures.contains(path);
293 }
294
295 uint32_t AssetManager::getTextureDescriptorIndex(const std::filesystem::path &path) {
296 TRACY_LOCK_GUARD(std::mutex, lock, textureMutex);
297 const auto it = textures.find(path.generic_string());
298 if (it != textures.end() && it->second && it->second->isDescriptorIndexInitialized()) {
299 return it->second->getDescriptorIndex();
300 }
301 return 0xFFFFFFFF;
302 }
303
304 Texture *AssetManager::registerTexture(const std::filesystem::path &path, Texture texture) {
305 TRACY_LOCK_GUARD(std::mutex, lock, textureMutex);
306 if (textures.contains(path.generic_string())) {
307 return textures.find(path.generic_string())->second;
308 }
309
310 texture.createResources();
311
312 uint32_t freeTextureIndex = textureAllocator.allocate();
313 texture.descriptorIndex = freeTextureIndex;
314 textureData[freeTextureIndex] = std::move(texture);
315
316 Texture *texturePtr = &textureData[freeTextureIndex].value();
317 textures[path.generic_string()] = texturePtr;
318 textureIndexMap.insert(freeTextureIndex, texturePtr);
319
320 // Queue texture for GPU upload via RenderingDataManager
321 if (renderer) {
322 renderer->getRenderingDataManager()->queueTextureForUpload(texturePtr);
323 }
324
325 PLOGI << "Texture " << path.generic_string() << " created.";
326 return textures[path.generic_string()];
327 }
328
330 uint32_t textureIndex = std::numeric_limits<uint32_t>::max();
331 TRACY_LOCK_GUARD(std::mutex, lock, textureMutex);
332 for (const auto &[path, texturePtr]: textures) {
333 if (texturePtr == texture) {
334 textureIndex = texturePtr->descriptorIndex;
335 break;
336 }
337 }
338
339 textureData[textureIndex]->reset();
340 textureData[textureIndex].reset();
341 textureIndexMap.remove_left(textureIndex);
342 }
343
344 Mesh *AssetManager::registerMesh(const std::filesystem::path &path, GltfLoader::GltfMeshData &gltfMeshData) {
345 TRACY_ZONE_SCOPED_NAMED("Registering mesh");
346 uint32_t meshIndex = std::numeric_limits<uint32_t>::max();
347 const std::string meshName = Mesh::createMeshName(path, gltfMeshData.getName()); {
348 TRACY_LOCK_GUARD(std::mutex, lock, meshesMutex);
349
350 const auto it = meshes.find(meshName);
351 if (it != meshes.end()) {
352 return it->second;
353 }
354
355 const uint32_t freeMeshIndex = meshAllocator.allocate();
356
357 meshData[freeMeshIndex].emplace(gltfMeshData, context, renderer);
358 meshData[freeMeshIndex].value().descriptorIndex = freeMeshIndex;
359 Mesh *meshPtr = &meshData[freeMeshIndex].value();
360 meshes[meshName] = meshPtr;
361 meshIndexMap.insert(freeMeshIndex, meshPtr);
362 meshIndex = freeMeshIndex;
363 }
364
365 meshData[meshIndex]->createResources();
366
367 return meshes[meshName];
368 }
369
371 TRACY_ZONE_SCOPED_NAMED("Unregistering mesh");
372 uint32_t meshIndex = std::numeric_limits<uint32_t>::max();
373
374 TRACY_LOCK_GUARD(std::mutex, lock, meshesMutex);
375 for (const auto &entry: meshes) {
376 if (entry.second == mesh) {
377 meshIndex = entry.second->descriptorIndex;
378 break;
379 }
380 }
381
382 meshData[meshIndex]->reset();
383 meshData[meshIndex].reset();
384 meshIndexMap.remove_left(meshIndex);
385
386 if (meshOffsets.find(mesh) != meshOffsets.end()) {
387 meshOffsets.erase(meshOffsets.find(mesh));
388 }
389 }
390
392 return textures.size();
393 }
394} // namespace EngineCore
constexpr uint32_t MAX_MESH_COUNT
Definition Settings.h:36
constexpr uint32_t MAX_TEXTURE_COUNT
Definition Settings.h:35
#define TRACY_LOCK_GUARD(type, varname, var)
#define TRACY_ZONE_SCOPED_NAMED(name)
The model asset pipeline loads a gltf scene and loads and loads the mesh and material data....
Infrastructure to load images into the ecs.
NamedThreadPool * threadedCalculation
uint32_t getMeshletCount(const std::vector< const Mesh * > &meshes) const
uint32_t getMeshOffset(Mesh *mesh) const
std::unordered_map< MaterialShader *, uint32_t > shaderOffsets
MaterialShader * registerShader(MaterialShader shader, const PipelineNames &materialName)
BidirectionalMap< uint32_t, Mesh * > meshIndexMap
Ecs::ModelAssetPipeline & getMeshAssetPipeline()
uint32_t getTextureDescriptorIndex(const std::filesystem::path &path)
Gets the descriptor index of a loaded texture by path.
DescriptorIndexAllocator textureAllocator
std::vector< MaterialShader * > shaders
std::unordered_map< PipelineNames, VulkanBuffer > materialStorageBuffers
void unregisterMesh(Mesh *mesh)
BidirectionalMap< uint32_t, Texture * > textureIndexMap
MeshAsset * getMeshAsset(const Asset::Path &asset)
Get a mesh from the asset manager. If it does not exist it requests the asset from the asset loader.
DescriptorIndexAllocator shaderAllocator
DescriptorIndexAllocator meshAllocator
void unregisterTexture(Texture *texture)
std::unordered_map< PipelineNames, MaterialShader * > shadersByName
ApplicationContext * context
std::unordered_map< std::filesystem::path, Texture *, PathHasher > textures
void unregisterShader(MaterialShader *shader)
MeshAssetManager * meshAssetManager
MaterialShader * getShaderByName(const std::string &shaderName)
Ecs::TextureAssetPipeline texturePipeline
VulkanBuffer & getMaterialStorageBufferByName(PipelineNames name)
std::unordered_map< Mesh *, uint32_t > meshOffsets
bool doesTextureAlreadyExist(const std::filesystem::path &path)
Checks if a texture has already been loaded.
TextureAssetManager * textureAssetManager
NamedThreadPool * threadPool
std::vector< const Mesh * > getAllMeshes() const
Gets a copy of all meshes which are currently loaded in the asset manager.
std::vector< Texture * > texturesToCopyImageData
std::array< std::optional< Mesh >, MAX_MESH_COUNT > meshData
uint32_t getTotalPrimitiveCount() const
Mesh * registerMesh(const std::filesystem::path &path, GltfLoader::GltfMeshData &gltfMeshData)
void setRenderingDataManager(RenderingDataManager *renderingDataManager)
Sets the RenderingDataManager on asset pipelines for hook notifications.
void attachToRenderer(Renderer *renderer)
Sets what renderer the render process belongs to.
std::vector< const MeshPrimitive * > getMeshPrimitivesFromMeshes(const std::vector< const Mesh * > &meshes) const
PipelineNames materialNameFromString(const std::string &string)
uint32_t getImageCount() const
Ecs::ModelAssetPipeline modelAssetPipeline
MaterialAssetManager * materialAssetManager
std::unordered_map< std::filesystem::path, Mesh *, PathHasher > meshes
ModelAssetManager * modelAssetManager
std::array< std::optional< MaterialShader >, 100 > shaderData
Ecs::TextureAssetPipeline & getTextureAssetPipeline()
void loadEcsModel(const std::filesystem::path &path)
Submits a gltf model for loading. You provide the path of the model to load. This can include 3D data...
std::vector< VkDescriptorImageInfo > getTextureDescriptorInfos() const
void loadEcsTexture(const std::filesystem::path &path)
Loads a texture (.png / .jpg / .exr)
uint32_t getShaderCount() const
std::vector< MaterialShader * > getShaders() const
std::vector< Texture * > getTexturesToUpload()
Texture * registerTexture(const std::filesystem::path &path, Texture texture)
Registers a texture with the texture manager which prevents the same texture from being loaded twice.
std::array< std::optional< Texture >, MAX_TEXTURE_COUNT > textureData
bool doesMeshAlreadyExist(const std::filesystem::path &meshPath) const
Checks if a mesh is already present in the loaded meshes in RAM.
Stores mesh data with their primitives.
Definition MeshAsset.h:54
The mesh asset stores geometry data and.
Definition MeshAsset.h:15
static std::string createMeshName(const std::filesystem::path &path, const std::string &meshName)
Definition Mesh.cpp:144
The model asset is used to bind together all files of one gtlf model. The idea is that textures,...
uint32_t descriptorIndex
Definition Texture.h:99
RAII wrapper for Vulkan buffer and device memory.
Log category system implementation.
T UnpackOptional(std::optional< T > var)
Definition Optional.h:7
std::filesystem::path getFilePath() const
Definition AssetPath.h:17