Skip to content

Commit

Permalink
Updated documentation for the GLTF resource manager + few minor impro…
Browse files Browse the repository at this point in the history
…vements
  • Loading branch information
TheMostDiligent committed Apr 14, 2023
1 parent 6ddabbe commit 4a4f62c
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 17 deletions.
16 changes: 15 additions & 1 deletion AssetLoader/interface/GLTFLoader.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,21 @@ struct Material

bool DoubleSided = false;

// Texture indices in Model.Textures array, for each attribute
// Texture indices in Model.Textures array, for each attribute.
// _________________ _______________________ __________________
// | | | | | |
// | GLTF Model | | Material | | Model |
// | | | | | |
// | | | TextureIds | | Textures |
// | "normalTexture" | | [ | | 3 | | ] | | [ | | | ] |
// | | | | A | | | A |
// | |_ _ _ _ _ |_ _ _2_ _ |_ _ _ _ _ | |_ _ _ _ __|_ _3_ _|_ _ _ _ _ _ _ _| |
// | | A | | | |
// |_________________| | |_______________________| |___________________|
// |
// Defined by
// ModeCI.TextureAttributes
//
std::array<int, NumTextureAttributes> TextureIds = {};
};

Expand Down
72 changes: 66 additions & 6 deletions AssetLoader/interface/GLTFResourceManager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,16 @@ class ResourceManager final : public ObjectBase<IObject>
public:
using TBase = ObjectBase<IObject>;

/// Vertex layout key used to select the vertex pool.
///
/// \remarks
/// When vertex data is split between multiple buffers, the offsets in each buffer must be
/// consistent. For example, suppose we store position in buffer 0 (12 bytes) and normals + UVs
/// in buffer 1 (20 bytes).
/// If the the first allocation contains 100 vertices, the offsets for the second allocation will be
/// 1200 and 2000 bytes correspondingly.
/// If these offsets are not consistent, the vertex shader will read incorrect data.
/// Vertex layout key is used to group compatible layouts in the same vertex pool.
struct VertexLayoutKey
{
struct ElementDesc
Expand Down Expand Up @@ -130,7 +140,7 @@ class ResourceManager final : public ObjectBase<IObject>
Uint32 NumTexAtlases = 0;

/// Default texture atlas description that is used to create texture
/// atlase not explicitly specified in pTexAtlasCIs.
/// atlas not explicitly specified in pTexAtlasCIs.
/// If DefaultAtlasDesc.Desc.Type is RESOURCE_DIM_UNDEFINED,
/// additional atlases will not be created.
DynamicTextureAtlasCreateInfo DefaultAtlasDesc;
Expand All @@ -142,36 +152,86 @@ class ResourceManager final : public ObjectBase<IObject>
DefaultVertexPoolDesc DefaultPoolDesc;
};

/// Creates a new resource manager instance.
static RefCntAutoPtr<ResourceManager> Create(IRenderDevice* pDevice,
const CreateInfo& CI);

/// Allocates texture space in the texture atlas that matches the specified format.

/// \param[in] Fmt - Texture format.
/// \param[in] Width - Texture width.
/// \param[in] Height - Texture height.
/// \param[in] CacheId - Optional cache ID.
/// \param[in] pUserData - Optional user data to set in the texture atlas suballocation.
///
/// \remarks If the texture atlas for the given format does not exist and if the default
/// atlas description allows creating new atlases (Desc.Type != RESOURCE_DIM_UNDEFINED),
/// new atlas will be added. Otherwise, the function will return null.
RefCntAutoPtr<ITextureAtlasSuballocation> AllocateTextureSpace(TEXTURE_FORMAT Fmt,
Uint32 Width,
Uint32 Height,
const char* CacheId = nullptr,
IObject* pUserData = nullptr);

/// Finds texture allocation in the texture atlas that matches the specified cache ID.
RefCntAutoPtr<ITextureAtlasSuballocation> FindTextureAllocation(const char* CacheId);

RefCntAutoPtr<IBufferSuballocation> AllocateIndices(Uint32 Size, Uint32 Alignment);
/// Allocates indices in the index buffer.
RefCntAutoPtr<IBufferSuballocation> AllocateIndices(Uint32 Size, Uint32 Alignment = 4);

/// Allocates vertices in the vertex pool that matches the specified layout.

/// \param[in] LayoutKey - Vertex layout key, see VertexLayoutKey.
/// \param[in] VertexCount - The number of vertices to allocate.
///
/// \remarks If the vertex pool for the given key does not exist and if the default
/// pool description allows creating new pools (VertexCount != 0),
/// new pool will be added.
/// Otherwise, the function will return null.
RefCntAutoPtr<IVertexPoolAllocation> AllocateVertices(const VertexLayoutKey& LayoutKey, Uint32 VertexCount);


/// Returns the combined texture atlas version, i.e. the sum of the texture versions of all
/// atlases.
Uint32 GetTextureVersion();

/// Returns the index buffer version.
Uint32 GetIndexBufferVersion(Uint32 Index) const;

/// Returns the combined vertex pool version, i.e. the sum all vertex pool versions.
Uint32 GetVertexPoolsVersion();

IBuffer* GetIndexBuffer(IRenderDevice* pDevice, IDeviceContext* pContext);
/// Returns a pointer to the index buffer.
IBuffer* GetIndexBuffer(IRenderDevice* pDevice, IDeviceContext* pContext);

/// Returns a pointer to the vertex pool for the given key.
/// If the pool does not exist, null is returned.
IVertexPool* GetVertexPool(const VertexLayoutKey& Key);
ITexture* GetTexture(TEXTURE_FORMAT Fmt, IRenderDevice* pDevice, IDeviceContext* pContext);

/// Returns the atlas texture for the given format.
/// If the atlas does not exist, null is returned.
ITexture* GetTexture(TEXTURE_FORMAT Fmt, IRenderDevice* pDevice, IDeviceContext* pContext);

// NB: can't return reference here!
TextureDesc GetAtlasDesc(TEXTURE_FORMAT Fmt);

/// Returns the texture atlas allocation alignment for the given format.
Uint32 GetAllocationAlignment(TEXTURE_FORMAT Fmt, Uint32 Width, Uint32 Height);

BufferSuballocatorUsageStats GetIndexBufferUsageStats();
/// Returns the index buffer usage stats.
BufferSuballocatorUsageStats GetIndexBufferUsageStats();

/// Returns the texture atlas usage stats.
///
/// If fmt is not TEX_FORMAT_UNKNOWN, returns the stats for the atlas matching the specified format.
/// Otherwise, returns the net usage stats for all atlases.
DynamicTextureAtlasUsageStats GetAtlasUsageStats(TEXTURE_FORMAT Fmt = TEX_FORMAT_UNKNOWN);
VertexPoolUsageStats GetVertexPoolUsageStats(const VertexLayoutKey& Key = VertexLayoutKey{});

/// Returns the vertex pool usage stats.
///
/// If the key is not equal the default key, returns the stats for the vertex pool matching the key.
/// Otherwise, returns the net usage stats for all pools.
VertexPoolUsageStats GetVertexPoolUsageStats(const VertexLayoutKey& Key = VertexLayoutKey{});

private:
template <typename AllocatorType, typename ObjectType>
Expand Down
32 changes: 22 additions & 10 deletions AssetLoader/src/GLTFResourceManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,12 +169,18 @@ RefCntAutoPtr<ITextureAtlasSuballocation> ResourceManager::AllocateTextureSpace(

RefCntAutoPtr<IDynamicTextureAtlas> pAtlas;
CreateDynamicTextureAtlas(nullptr, AtalsCreateInfo, &pAtlas);
DEV_CHECK_ERR(pAtlas, "Failed to create new texture atlas");

cache_it = m_Atlases.emplace(Fmt, std::move(pAtlas)).first;
if (pAtlas)
{
cache_it = m_Atlases.emplace(Fmt, std::move(pAtlas)).first;
}
else
{
DEV_ERROR("Failed to create new texture atlas");
return {};
}
}
}
// Allocate outside of mutex
// Allocate outside of the mutex lock
cache_it->second->Allocate(Width, Height, &pAllocation);
pAllocation->SetUserData(pUserData);
}
Expand Down Expand Up @@ -241,9 +247,9 @@ RefCntAutoPtr<IVertexPoolAllocation> ResourceManager::AllocateVertices(const Ver
ElemDesc.Usage = m_DefaultVertPoolDesc.Usage;
ElemDesc.CPUAccessFlags = m_DefaultVertPoolDesc.CPUAccessFlags;
ElemDesc.Mode = m_DefaultVertPoolDesc.Mode;
if (ElemDesc.Usage == USAGE_SPARSE && (ElemDesc.BindFlags & BIND_VERTEX_BUFFER) != 0 && m_DeviceType == RENDER_DEVICE_TYPE_D3D11)
if (ElemDesc.Usage == USAGE_SPARSE && (ElemDesc.BindFlags & (BIND_VERTEX_BUFFER | BIND_INDEX_BUFFER)) != 0 && m_DeviceType == RENDER_DEVICE_TYPE_D3D11)
{
// Direct3D11 does not support sparse vertex buffers
// Direct3D11 does not support sparse vertex or index buffers
ElemDesc.Usage = USAGE_DEFAULT;
}
}
Expand All @@ -252,13 +258,19 @@ RefCntAutoPtr<IVertexPoolAllocation> ResourceManager::AllocateVertices(const Ver

RefCntAutoPtr<IVertexPool> pVtxPool;
CreateVertexPool(nullptr, PoolCI, &pVtxPool);
DEV_CHECK_ERR(pVtxPool, "Failed to create new vertex pool");

pool_it = m_VertexPools.emplace(LayoutKey, std::move(pVtxPool)).first;
if (pVtxPool)
{
pool_it = m_VertexPools.emplace(LayoutKey, std::move(pVtxPool)).first;
}
else
{
DEV_ERROR("Failed to create new vertex pool");
return {};
}
}
}

// Allocate outside of mutex
// Allocate outside of the mutex lock
RefCntAutoPtr<IVertexPoolAllocation> pVertices;
pool_it->second->Allocate(VertexCount, &pVertices);
return pVertices;
Expand Down

0 comments on commit 4a4f62c

Please sign in to comment.