Vulkan Schnee 0.0.1 (22840dc8)
High-performance rendering engine
Loading...
Searching...
No Matches
AssetManager.h
1#pragma once
2#include "DescriptorIndexAllocator.h"
3#include "Engine/Animation/AnimationAsset.h"
4#include "Engine/Animation/AnimationAssetRef.h"
5#include "Engine/Animation/SkinAsset.h"
6#include "Engine/Animation/SkinAssetRef.h"
7#include "Engine/Audio/AudioAsset.h"
8#include "Engine/Audio/AudioAssetRef.h"
9#include "Engine/Core/Settings.h"
10#include "Engine/Ecs/FrameProcessing.h"
11#include "Engine/Logging/TracyMacros.hpp"
12#include "Engine/Material/MaterialAsset.h"
13#include "Engine/Material/MaterialAssetRef.h"
14#include "Engine/Texture/CubemapTexture.h"
15#include "Engine/Texture/Texture.h"
16#include "Engine/Texture/TextureAsset.h"
17#include "Engine/Texture/TextureAssetRef.h"
18#include "Engine/Texture/TextureHandleRegistry.h"
19#include "Engine/Texture/RuntimeTextureDescriptorLease.h"
20#include "MeshAsset.h"
21#include "MeshAssetRef.h"
22
23#include <Engine/Math/BidirectionalMap.h>
24#include <Engine/Texture/TextureLoadData.h>
25#include <filesystem>
26#include <memory>
27#include <optional>
28#include <string>
29#include <type_traits>
30#include <unordered_map>
31#include <unordered_set>
32
33namespace Engine::Entities
34{
35 class GltfSpawner;
36} // namespace Engine::Entities
37
38namespace Engine::Rendering
39{
40 class Renderer;
41} // namespace Engine::Rendering
42
43class NamedThreadPool;
44
45namespace Engine::Assets
46{
47 class Material;
48 class Mesh;
49 class ModelAssetManager;
50 class MeshAssetManager;
51 class RuntimeTexture;
52 class Texture;
53} // namespace Engine::Assets
54
55namespace Engine::Core
56{
58 class RenderingDataManager;
59 class TextureManager;
60
65 {
71 std::size_t operator()( const std::filesystem::path & p ) const noexcept
72 {
73 return std::hash<std::string>{}( p.string() ); // Hash the string representation
74 }
75 };
76
81 {
82 glm::vec3 position;
83 uint32_t packedNormal;
84 uint32_t packedColor;
85 uint32_t packedTexCoord;
86 };
87
97 inline uint32_t packNormalA2B10G10R10_SNORM( const glm::vec3 & n )
98 {
99 // Clamp input just in case
100 float x = std::max( -1.0f, std::min( 1.0f, n.x ) );
101 float y = std::max( -1.0f, std::min( 1.0f, n.y ) );
102 float z = std::max( -1.0f, std::min( 1.0f, n.z ) );
103
104 // Scale to signed 10-bit range [-511, 511]
105 int32_t ix = static_cast<int32_t>( std::round( x * 511.0f ) );
106 int32_t iy = static_cast<int32_t>( std::round( y * 511.0f ) );
107 int32_t iz = static_cast<int32_t>( std::round( z * 511.0f ) );
108
109 // Pack into uint32_t (masking handles two's complement correctly)
110 // Layout: | 2 unused | 10 bits B | 10 bits G | 10 bits R |
111 return ( static_cast<uint32_t>( iz & 0x3FF ) << 20 ) | ( static_cast<uint32_t>( iy & 0x3FF ) << 10 ) |
112 ( static_cast<uint32_t>( ix & 0x3FF ) );
113 // Alpha bits (highest 2) remain 0
114 }
115
124 inline uint32_t packColorR8G8B8A8_UNORM( const glm::vec3 & c )
125 {
126 // Clamp input
127 float r = std::max( 0.0f, std::min( 1.0f, c.x ) );
128 float g = std::max( 0.0f, std::min( 1.0f, c.y ) );
129 float b = std::max( 0.0f, std::min( 1.0f, c.z ) );
130
131 // Scale to [0, 255]
132 uint32_t ur = static_cast<uint32_t>( std::round( r * 255.0f ) );
133 uint32_t ug = static_cast<uint32_t>( std::round( g * 255.0f ) );
134 uint32_t ub = static_cast<uint32_t>( std::round( b * 255.0f ) );
135 uint32_t ua = 255; // Fully opaque alpha
136
137 // Pack (assuming typical RGBA little-endian layout)
138 return ( ua << 24 ) | ( ub << 16 ) | ( ug << 8 ) | ur;
139 }
140
146 inline uint32_t packTexCoordR16G16_SFLOAT( const glm::vec2 & tc )
147 {
148 // Use glm's packing function (requires <glm/gtc/packing.hpp>)
149 // It converts two floats to two 16-bit half-floats and packs them.
150 return glm::packHalf2x16( tc );
151 }
152
157 {
158 uint32_t index = 0u;
159
161 std::shared_ptr<Assets::Texture> texture = nullptr;
162
168 template <typename T>
169 bool operator>( const T & other )
170 {
171 return index > other.index;
172 }
173
179 template <typename T>
180 bool operator<( const T & other )
181 {
182 return index < other.index;
183 }
184 };
185
194 {
197 friend Core::TextureManager;
199
200 public:
213
234 template <typename AssetClass, typename Key>
235 [[nodiscard]] auto getAsset( const Key & asset )
236 {
237 if constexpr ( std::is_same_v<AssetClass, Assets::Mesh> )
238 {
239 static_assert(
240 std::is_same_v<std::decay_t<Key>, Asset::MeshPath>,
241 "Mesh assets are keyed by Asset::MeshPath"
242 );
243
244 MeshAssetRef ref = meshAssetManager->getOrCreateRef( asset );
245 (void)getMeshAsset( asset );
246 return ref;
247 }
248 else if constexpr ( std::is_same_v<AssetClass, Assets::Audio> )
249 {
250 static_assert(
251 std::is_same_v<std::decay_t<Key>, Asset::Path> ||
252 std::is_same_v<std::decay_t<Key>, std::filesystem::path>,
253 "Audio assets are keyed by Asset::Path"
254 );
255
256 return loadAudioAsset( Asset::Path( asset ) );
257 }
258 else if constexpr ( std::is_same_v<AssetClass, Assets::Animation> )
259 {
260 static_assert(
261 std::is_same_v<std::decay_t<Key>, Asset::MeshPath>,
262 "Animation assets are keyed by Asset::MeshPath"
263 );
264
265 AnimationAssetRef ref = animationAssetManager_->getOrCreateRef( asset );
266 if ( animationAssetManager_->getAssetLoadingState( asset ) == Asset::UNLOADED )
267 {
268 loadEcsModel( asset.getFilePath() );
269 }
270 return ref;
271 }
272 else if constexpr ( std::is_same_v<AssetClass, Assets::Material> )
273 {
274 static_assert(
275 std::is_same_v<std::decay_t<Key>, Asset::MeshPath>,
276 "Material assets are keyed by Asset::MeshPath"
277 );
278
279 return materialAssetManager->getOrCreateRef( asset );
280 }
281 else if constexpr ( std::is_same_v<AssetClass, Assets::Skin> )
282 {
283 static_assert(
284 std::is_same_v<std::decay_t<Key>, Asset::MeshPath>,
285 "Skin assets are keyed by Asset::MeshPath"
286 );
287
288 SkinAssetRef ref = skinAssetManager_->getOrCreateRef( asset );
289 if ( skinAssetManager_->getAssetLoadingState( asset ) == Asset::UNLOADED )
290 {
291 loadEcsModel( asset.getFilePath() );
292 }
293 return ref;
294 }
295 else if constexpr ( std::is_same_v<AssetClass, Assets::Texture> )
296 {
297 static_assert(
298 std::is_same_v<std::decay_t<Key>, Asset::Path> ||
299 std::is_same_v<std::decay_t<Key>, std::filesystem::path>,
300 "Texture assets are keyed by Asset::Path"
301 );
302
303 const Asset::Path pathKey( asset );
304 TextureAssetRef ref = textureAssetManager->getOrCreateRef( pathKey );
305 const Asset::LoadState state = textureAssetManager->getAssetLoadingState( pathKey );
306 if ( state != Asset::LOADED && state != Asset::REQUESTED_LOAD && state != Asset::LOADING )
307 {
308 loadEcsTexture( pathKey.getFilePath() );
309 }
310 return ref;
311 }
312 else
313 {
314 static_assert(
315 std::is_same_v<AssetClass, void>, "Unsupported asset type for AssetManager::getAsset<T>()"
316 );
317 }
318 }
319
326
332
339
348 void attachToRenderer( Rendering::Renderer * renderer );
349
358 void setRenderingDataManager( RenderingDataManager * renderingDataManager );
359
360 private:
365 void loadEcsModel( const std::filesystem::path & path );
366
371 void loadEcsTexture( const std::filesystem::path & path );
372
373 public:
383 Assets::CubemapTexture * loadEcsCubemap( const std::filesystem::path & path );
384
394 [[nodiscard]] uint32_t getTextureDescriptorIndex( const std::filesystem::path & path );
395
402 [[nodiscard]] uint32_t getTextureDescriptorIndex(
403 const std::filesystem::path & path,
405 );
406
418 const std::filesystem::path & path,
420 );
421
428 template <Assets::TextureType Type>
430 const std::filesystem::path & path
431 )
432 {
434 }
435
440 uint32_t getImageCount() const;
441
447 void cleanup();
448
453 std::vector<VkDescriptorImageInfo> getTextureDescriptorInfos() const;
454
460
466
472
478
486
493
500
506 [[nodiscard]] Assets::Audio * getAudioAsset( const Asset::Path & path );
507
513 {
514 return audioAssetManager_;
515 }
516
517 private:
523 [[nodiscard]] Assets::Mesh * getMeshAsset( const Asset::MeshPath & asset );
524
525 public:
531 {
533 }
534
539 [[nodiscard]] Assets::ModelAssetManager * getModelAssetManager() const
540 {
541 return modelAssetManager;
542 }
543
549 {
550 return meshAssetManager;
551 }
552
558 {
559 return skinAssetManager_;
560 }
561
570
579
589
590 private:
592
593 void releaseRuntimeTextureDescriptorIndex( uint32_t descriptorIndex );
594
595 NamedThreadPool * threadPool_ = nullptr;
596 NamedThreadPool * threadedCalculation_ = nullptr;
597
601 Assets::ModelAssetManager * modelAssetManager;
604
605 // IMPORTANT: textureHandleRegistry_ must be declared BEFORE assetImportPipeline
606 // because the model pipeline's constructor receives 'this' and may access the registry.
607 // C++ initializes members in declaration order, not initializer list order.
610
613
614 public:
619 NamedThreadPool * getCalculationPool() const
620 {
622 }
623
628 NamedThreadPool * getAssetLoaderPool() const
629 {
630 return threadPool_;
631 }
632
633 private:
635
637 Rendering::Renderer * renderer = nullptr;
638
639 std::unordered_map<
644 std::unordered_map<std::string, std::vector<Assets::Textures::TextureIdentityKey>> textureIdentitiesByPath_;
645 std::unordered_map<std::filesystem::path, std::unique_ptr<Assets::CubemapTexture>, PathHasher>
648
649 std::array<std::optional<Assets::RuntimeTexture>, MAX_TEXTURE_COUNT> textureData;
651 std::unordered_set<uint32_t> runtimeTextureDescriptorIndices_;
652 std::unordered_set<uint32_t> fileTextureDescriptorIndices_;
654
660 bool doesTextureAlreadyExist( const std::filesystem::path & path );
661
670 registerTexture( const std::filesystem::path & path, Assets::RuntimeTexture texture );
671
681 const std::filesystem::path & path,
684 );
685
697 registerTextureFromPrepared( const std::filesystem::path & path, Assets::RuntimeTexture texture );
698
708 const std::filesystem::path & path,
711 );
712
721 replaceTextureFromPrepared( const std::filesystem::path & path, Assets::RuntimeTexture texture );
722
732 const std::filesystem::path & path,
735 );
736
742
747
754
755 TRACY_LOCKABLE( std::mutex, textureMutex, "Texture mutex" );
756
757 std::vector<TextureStorage> texturesToUpload{};
758 std::vector<Assets::RuntimeTexture *> texturesToCopyImageData;
759 };
760} // namespace Engine::Core
Maintains a one-to-one mapping that can be queried from either side.
Stores animation clips keyed by their source mesh path.
Manages audio assets by filesystem path, providing dedup and lookup.
Definition AudioAsset.h:80
Holds decoded PCM audio data as an engine asset.
Definition AudioAsset.h:14
Owns Vulkan resources for a sampled cubemap texture.
Loads glTF files and converts tinygltf data into engine asset data.
Definition GltfLoader.h:39
Asset manager for materials keyed by source file path and material name.
the material asset is another wrapper for asset data which is stored in entt. It has the EngineCore::...
Stores mesh data with their primitives.
Definition MeshAsset.h:51
The mesh asset stores geometry data and.
Definition MeshAsset.h:20
Move-only ownership of one runtime texture descriptor slot.
Runtime-owned Vulkan texture resource.
Definition Texture.h:33
Stores skin and skeleton binding data keyed by source mesh path.
Definition SkinAsset.h:93
Asset manager for texture assets keyed by filesystem path.
Type-erased texture handle for runtime storage.
static constexpr uint32_t INVALID_ID
Sentinel ID for an invalid handle.
Wrapper for texture data.
Central registry for texture handles, providing O(1) descriptor index lookup.
Type-safe texture handle wrapper providing compile-time type safety.
The application context is the core class which stores the basic openxr and vulkan objects.
bool doesTextureAlreadyExist(const std::filesystem::path &path)
Checks whether a texture path has a loaded identity entry.
Ecs::AssetImportPipeline & getAssetImportPipeline()
Gets the master asset import pipeline.
Assets::ModelAssetManager * modelAssetManager
void unloadAllData()
Discards pending work and clears loaded asset manager state.
Assets::Mesh * getMeshAsset(const Asset::MeshPath &asset)
Gets a mesh asset by path or requests its model if it is not loaded.
DescriptorIndexAllocator textureAllocator
void discardSceneLoadingData()
Drops queued or in-flight scene asset loading work.
Assets::TextureAssetRef TextureAssetRef
Legacy asset reference type for texture assets.
AssetManager()
Creates an asset manager without an application context.
Assets::MaterialAssetManager * materialAssetManager
Assets::Textures::TextureHandleRegistry * getTextureHandleRegistry()
Gets the texture handle registry for O(1) descriptor index lookups.
Rendering::Renderer * renderer
std::unordered_map< std::filesystem::path, std::unique_ptr< Assets::CubemapTexture >, PathHasher > cubemapTextures
Assets::SkinAssetManager * skinAssetManager_
Assets::MaterialAssetManager * getMaterialAssetManager() const
Gets the material asset manager for material lookups.
Assets::TextureHandle getOrCreateTextureHandleWithSlot(const std::filesystem::path &path, Assets::TextureType type)
Gets or creates a texture handle and reserves a stable descriptor slot for it.
uint32_t getImageCount() const
Gets the number of registered runtime texture identities.
auto getAsset(const Key &asset)
Gets or creates an asset reference and requests loading when needed.
std::vector< TextureStorage > texturesToUpload
Assets::RuntimeTexture * replaceTextureFromPrepared(const std::filesystem::path &path, Assets::RuntimeTexture texture)
Replaces an already registered texture while preserving its descriptor index.
Assets::AudioAssetRef AudioAssetRef
Legacy asset reference type for audio assets.
Assets::MeshAssetRef MeshAssetRef
Legacy asset reference type for mesh assets.
void setRenderingDataManager(RenderingDataManager *renderingDataManager)
Sets the rendering data manager used by asset pipelines.
Assets::Textures::TextureHandleRegistry textureHandleRegistry_
Registry for type-safe texture handles.
Ecs::AudioAssetPipeline & getAudioAssetPipeline()
Gets the audio loading pipeline.
std::unordered_map< Assets::Textures::TextureIdentityKey, Assets::RuntimeTexture *, Assets::Textures::TextureIdentityKeyHash > textures
Assets::RuntimeTexture * registerTextureFromPrepared(const std::filesystem::path &path, Assets::TextureType type, Assets::RuntimeTexture texture)
Registers a typed texture whose Vulkan resources are already created.
Assets::RuntimeTextureDescriptorLease reserveRuntimeTextureDescriptor()
Reserves a stable descriptor index for a runtime-generated sampled image.
void cleanup()
Waits for asset jobs and releases loaded runtime texture resources.
void loadEcsTexture(const std::filesystem::path &path)
Submits a texture file for asynchronous loading.
Assets::Loaders::GltfLoader gltfLoader
~AssetManager()
Destroys owned asset managers and worker pools.
Assets::MeshAssetManager * meshAssetManager
std::vector< VkDescriptorImageInfo > getTextureDescriptorInfos() const
Builds descriptor image info records for resident textures.
NamedThreadPool * threadPool_
Assets::AudioAssetManager * getAudioAssetManager() const
Gets the audio asset manager for direct access.
Assets::AudioAssetManager * audioAssetManager_
uint32_t getTextureDescriptorIndex(const std::filesystem::path &path, Assets::TextureType type)
Gets the descriptor index of a resident texture by path and semantic type.
Assets::Audio * getAudioAsset(const Asset::Path &path)
Gets a loaded audio asset by path.
Assets::AnimationAssetRef AnimationAssetRef
Legacy asset reference type for animation assets.
AssetManager(ApplicationContext *context)
Creates an asset manager bound to an application context.
Assets::MaterialAssetRef MaterialAssetRef
Legacy asset reference type for material assets.
Assets::AnimationAssetManager * animationAssetManager_
void unregisterTexture(Assets::RuntimeTexture *texture)
Unregisters a runtime texture and clears its descriptor slot.
Assets::RuntimeTexture * registerTexture(const std::filesystem::path &path, Assets::RuntimeTexture texture)
Creates Vulkan resources for a texture and registers it as file-backed texture data.
std::unordered_set< uint32_t > fileTextureDescriptorIndices_
Assets::ModelAssetManager * getModelAssetManager() const
Gets the model asset manager for model and glTF loading state lookups.
Assets::RuntimeTexture * registerTextureFromPrepared(const std::filesystem::path &path, Assets::RuntimeTexture texture)
Registers a texture whose Vulkan resources are already created.
void loadEcsModel(const std::filesystem::path &path)
Submits a glTF model file for asynchronous loading.
Assets::TextureAssetManager * textureAssetManager
Assets::RuntimeTexture * registerTexture(const std::filesystem::path &path, Assets::TextureType type, Assets::RuntimeTexture texture)
Creates Vulkan resources for a typed texture and registers it as file-backed texture data.
std::vector< Assets::RuntimeTexture * > texturesToCopyImageData
Ecs::TextureAssetPipeline & getTextureAssetPipeline()
Gets the texture loading pipeline.
void ensureFallbackTextureLocked()
Creates the built-in fallback texture when it does not already exist.
NamedThreadPool * getAssetLoaderPool() const
Gets the worker pool used for asynchronous asset loading.
void unloadRuntimeTextures()
Releases all runtime texture data and descriptor reservations owned by this manager.
Ecs::AssetImportPipeline assetImportPipeline
NamedThreadPool * getCalculationPool() const
Gets the worker pool used for asset-side CPU calculations.
NamedThreadPool * threadedCalculation_
void attachToRenderer(Rendering::Renderer *renderer)
Attaches the renderer used for texture uploads and descriptor reservation notifications.
Assets::SkinAssetRef SkinAssetRef
Legacy asset reference type for skin assets.
std::unordered_map< std::string, std::vector< Assets::Textures::TextureIdentityKey > > textureIdentitiesByPath_
BidirectionalMap< uint32_t, Assets::RuntimeTexture * > textureIndexMap
Assets::CubemapTexture * loadEcsCubemap(const std::filesystem::path &path)
Loads a six-face cubemap asset from a directory.
void releaseRuntimeTextureDescriptorIndex(uint32_t descriptorIndex)
uint32_t getTextureDescriptorIndex(const std::filesystem::path &path)
Gets the descriptor index of a resident texture by path.
Assets::AnimationAssetManager * getAnimationAssetManager() const
Gets the animation asset manager for direct access.
Assets::MeshAssetManager * getMeshAssetManager() const
Gets the mesh asset manager for mesh asset lookups.
ApplicationContext * context
std::unordered_set< uint32_t > runtimeTextureDescriptorIndices_
Assets::RuntimeTexture * replaceTextureFromPrepared(const std::filesystem::path &path, Assets::TextureType type, Assets::RuntimeTexture texture)
Replaces an already registered typed texture while preserving its descriptor index.
std::array< std::optional< Assets::RuntimeTexture >, MAX_TEXTURE_COUNT > textureData
Assets::SkinAssetManager * getSkinAssetManager() const
Gets the skin asset manager for direct access.
AudioAssetRef loadAudioAsset(const Asset::Path &path)
Submits an audio file for async loading through the audio pipeline.
Assets::TypedTextureHandle< Type > getOrCreateTextureHandleWithSlot(const std::filesystem::path &path)
Gets or creates a typed texture handle and reserves a stable descriptor slot for it.
Ecs::ModelAssetPipeline & getMeshAssetPipeline()
Gets the glTF model loading pipeline.
Use this class to manage a finite amount of memory. The idea is to have an array which stores objects...
Master asset import pipeline that dispatches asset submissions to the texture, model and audio sub-pi...
Async pipeline for loading audio assets (WAV, FLAC, MP3)
The model asset pipeline loads a gltf scene and loads and loads the mesh and material data....
Infrastructure to load images into the ecs.
Utility class for spawning GLTF meshes into a scene.
Definition GltfSpawner.h:15
@ LOADED
All components of the asset have been loaded, and it is ready to be used.
Definition Asset.h:40
@ REQUESTED_LOAD
An asset has been requested to load and is waiting for an asset pipeline to start working on it.
Definition Asset.h:32
@ LOADING
While the asset is currently being processed in the asset pipeline.
Definition Asset.h:36
@ UNLOADED
When the asset is not loaded yet but the frame is already existing for the heavy data to be loaded in...
Definition Asset.h:27
CpuLoadingState LoadState
Alias used by the asset manager and refs.
Definition Asset.h:47
Asset::Ref< Asset::MeshPath, Animation > AnimationAssetRef
Asset reference to an animation loaded from a mesh asset path.
Asset::Ref< Asset::Path, Audio > AudioAssetRef
Asset reference to decoded audio data loaded from a filesystem path.
Asset::Ref< Asset::Path, Texture > TextureAssetRef
Asset reference to a texture loaded from a filesystem path.
Asset::Ref< Asset::MeshPath, Skin > SkinAssetRef
Asset reference to skin binding data loaded from a mesh asset path.
Asset::Ref< Asset::MeshPath, Mesh > MeshAssetRef
Asset reference to mesh geometry loaded from a mesh asset path.
Asset::Ref< Asset::MeshPath, Material > MaterialAssetRef
Asset reference to material data loaded from a mesh asset path.
TextureType
Represents the semantic type of a texture, determining its Vulkan format.
Definition TextureType.h:15
uint32_t packTexCoordR16G16_SFLOAT(const glm::vec2 &tc)
Packs a 2D texture coordinate into R16G16_SFLOAT layout.
uint32_t packColorR8G8B8A8_UNORM(const glm::vec3 &c)
Packs an RGB color into R8G8B8A8_UNORM layout with opaque alpha.
uint32_t packNormalA2B10G10R10_SNORM(const glm::vec3 &n)
Packs a signed normalized 3D normal into A2B10G10R10_SNORM layout.
Identifies a named mesh-like asset inside an asset file.
Definition AssetPath.h:89
Identifies a single asset file on disk.
Definition AssetPath.h:13
const std::filesystem::path & getFilePath() const
Gets the stored filesystem path.
Definition AssetPath.h:41
Hash functor for TextureIdentityKey.
Path and semantic type pair that uniquely identifies a texture handle.
Compact vertex format used by mesh packing code.
glm::vec3 position
Full-precision local-space position.
uint32_t packedNormal
Normal packed as A2B10G10R10_SNORM.
uint32_t packedTexCoord
Texture coordinate packed as R16G16_SFLOAT.
uint32_t packedColor
Vertex color packed as R8G8B8A8_UNORM.
Hash functor for filesystem paths used in unordered containers.
std::size_t operator()(const std::filesystem::path &p) const noexcept
Hashes a filesystem path by its string representation.
Texture asset entry paired with its descriptor index.
std::shared_ptr< Assets::Texture > texture
Managed texture asset.
bool operator<(const T &other)
Compares texture storage entries by descriptor index.
bool operator>(const T &other)
Compares texture storage entries by descriptor index.
uint32_t index
Descriptor or storage index assigned to the texture.