project-aster/samples/03_model_render/render_resource_manager.h

135 lines
3.0 KiB
C++

// =============================================
// Aster: pipeline_utils.h
// Copyright (c) 2020-2024 Anish Bhobe
// =============================================
#pragma once
#include "buffer.h"
#include "global.h"
#include <EASTL/deque.h>
#include <EASTL/stack.h>
#include <EASTL/vector_map.h>
struct Device;
struct Texture;
struct UniformStorageBuffer;
struct RenderResourceManager;
struct GpuResourceHandle
{
constexpr static u32 INVALID_HANDLE = MaxValue<u32>;
u32 m_Index = INVALID_HANDLE; // Default = invalid
[[nodiscard]] bool
IsInvalid() const
{
return m_Index == INVALID_HANDLE;
}
};
struct BufferHandle : GpuResourceHandle
{
};
struct TextureHandle : GpuResourceHandle
{
};
struct FreeList
{
eastl::stack<u32, eastl::deque<u32>> m_List;
u32 m_MaxVisited = 0;
u32 m_MaxCapacity = 16;
void
Init(u32 maxCapacity)
{
// MaxValue<u32> is 'invalid-handle' so you can't use it as a handle.
assert(maxCapacity < GpuResourceHandle::INVALID_HANDLE);
m_MaxCapacity = maxCapacity;
}
[[nodiscard]] u32
Alloc()
{
if (!m_List.empty())
{
const u32 value = m_List.top();
m_List.pop();
return value;
}
if (m_MaxVisited < m_MaxCapacity)
{
return m_MaxVisited++;
}
ERROR("Out of Handles.") THEN_ABORT(-1);
}
void
Free(u32 index)
{
WARN_IF(index >= m_MaxCapacity, "Trying to free an out-of-bounds index.");
if (index < m_MaxCapacity)
m_List.push(index);
}
};
struct RenderResourceManager
{
private:
union WriteInfo {
vk::DescriptorBufferInfo uBufferInfo;
vk::DescriptorImageInfo uImageInfo;
vk::BufferView uBufferView;
explicit WriteInfo(vk::DescriptorBufferInfo info);
explicit WriteInfo(vk::DescriptorImageInfo info);
explicit WriteInfo(vk::BufferView info);
};
enum class HandleType
{
eBuffer,
eTexture,
};
using WriteOwner = eastl::pair<HandleType, u32>;
eastl::deque<WriteInfo> m_WriteInfos;
eastl::vector<vk::WriteDescriptorSet> m_Writes;
eastl::vector<WriteOwner> m_WriteOwner;
vk::Sampler m_Sampler;
FreeList m_BufferFreeList;
FreeList m_TextureFreeList;
void EraseWrites(u32 handleIndex, HandleType handleType);
public:
const Device *m_Device;
constexpr static u32 BUFFER_BINDING_INDEX = 0;
constexpr static u32 TEXTURE_BINDING_INDEX = 1;
vk::DescriptorPool m_DescriptorPool;
vk::DescriptorSetLayout m_SetLayout;
vk::DescriptorSet m_DescriptorSet;
BufferHandle Commit(const StorageBuffer *storageBuffer);
void Release(BufferHandle handle);
TextureHandle Commit(const Texture *texture);
void Release(TextureHandle handle);
void Update();
// Ctor/Dtor
RenderResourceManager(const Device *device, u16 maxSize);
~RenderResourceManager();
DISALLOW_COPY_AND_ASSIGN(RenderResourceManager);
};