feat: 引入 RenderGraph、Application 框架、ECS 与资产句柄系统

架构分层(自上而下):
  App(SandboxApp) → Application(生命周期+事件) → Scene(ECS) / AssetManager(句柄) → Renderer → RenderGraph → Vulkan 模块

- RenderGraph:声明式帧图。虚拟资源+生成号句柄、死 pass 剔除、
  拓扑排序、资源生命周期、barrier 编译期预算(Synchronization2)、
  物理镜像池按帧槽位隔离(帧间竞争从根上消除)
- 帧同步修复:per-frame-slot 命令缓冲与 UBO ring(原先单份存在
  数据竞争);统一 kMaxFramesInFlight / FrameContext
- Application:生命周期钩子(OnInit/OnUpdate/OnRender/OnShutdown)
  + 事件系统(GLFW 回调 → POD 事件 → 类型化钩子);main 只 new 派生类
- ECS:自研稀疏集 Registry(Entity=(index,generation) 防悬空,
  O(1) 增删查,Each 取最小池遍历);Scene 延迟销毁队列;
  IdComponent{UUID} 稳定外部身份
- Assets:AssetManager + AssetHandle。组件存句柄不存裸指针/Ref
  (单一所有者 + 多使用者),Renderer 删除 LoadModel 改为纯消费
- 修复退出析构:成员析构前 GPU waitIdle(资产层先于 Renderer
  析构导致 VUID-00922 资源销毁时仍在使用)
- 引入 entt 子模块备用

validation 全程零错误零警告(RTX 5060 实测)
This commit is contained in:
2026-09-22 13:46:05 +08:00
parent 7d628f8d8a
commit 8afdd9b245
33 changed files with 3013 additions and 561 deletions
+35 -37
View File
@@ -8,14 +8,13 @@
#pragma once
#include <Engine/Core/Types.h>
#include <Engine/Core/FrameContext.h>
#include <Engine/RenderGraph/RenderGraph.h>
#include <vulkan/vulkan.hpp>
#include <chrono>
#include <vector>
#include "Engine/Vulkan/Texture.h"
#include <glm/glm.hpp>
#include "Model.h"
namespace Engine {
class Window;
@@ -24,16 +23,20 @@ namespace Engine {
class DescriptorManager;
class ShaderManager;
class Swapchain;
class CommandManager;
class SyncManager;
class Buffer;
class CommandManager;
class UniformBuffer;
class Model;
struct Object {
glm::mat4 transform = glm::mat4(1.0f);
Model* model = nullptr;
};
namespace ECS { class Scene; }
namespace Assets { class AssetManager; }
// Renderer 职责(收敛后):
// 1. 装配底层模块(Device/Swapchain/Sync/Command/Descriptor/Shader)
// 2. 声明并驱动 RenderGraph(pass 结构在这里组装)
// 3. Render(Scene&, AssetManager&):从 ECS 场景读取相机/灯光/渲染体,
// 经资产层解析句柄后绘制
// 不拥有场景,不加载资产(资产归 AssetManager,磁盘 IO 与这里无关)。
class Renderer {
public:
Renderer(Window& window);
@@ -42,15 +45,21 @@ namespace Engine {
Renderer(const Renderer&) = delete;
Renderer& operator=(const Renderer&) = delete;
void Render();
void Render(ECS::Scene& scene, Assets::AssetManager& assets);
// ---- 组合根(Application)装配其他模块时需要的访问器 ----
Device& GetDevice() const { return *m_Device; }
MemoryAllocator& GetAllocator() const { return *m_Allocator; }
DescriptorManager& GetDescriptorManager() const { return *m_DescriptorManager; }
vk::DescriptorSetLayout GetTextureSetLayout() const { return m_TextureSetLayout; }
private:
void RecordCommands(vk::CommandBuffer cmd, u32 imageIndex);
void TransitionImageLayout(vk::CommandBuffer cmd, vk::Image image,
vk::ImageLayout oldLayout, vk::ImageLayout newLayout);
void BuildGraph(); // 声明 pass 结构 + 首次 Compile
void HandleResize();
Window& m_Window;
// ---- 底层模块(析构序:后声明者先析构,RG 在 Device/Allocator 之前)----
Scope<Device> m_Device;
Scope<MemoryAllocator> m_Allocator;
Scope<DescriptorManager> m_DescriptorManager;
@@ -58,38 +67,27 @@ namespace Engine {
Scope<Swapchain> m_Swapchain;
Scope<SyncManager> m_SyncManager;
Scope<CommandManager> m_CommandManager;
Scope<Model> m_Model;
std::vector<Object> m_Objects;
Scope<UniformBuffer> m_UniformBuffer;
Scope<RG::RenderGraph> m_RenderGraph;
// ---- 管线装配(shader object 方案,无 vk::Pipeline)----
vk::PipelineLayout m_PipelineLayout;
vk::DescriptorSetLayout m_UBOSetLayout;
vk::DescriptorSet m_UBODescriptorSet;
vk::DescriptorSetLayout m_TextureSetLayout;
std::vector<vk::DescriptorSet> m_UBODescriptorSets; // 每帧槽位一个
vk::ShaderEXT m_VertShader{};
vk::ShaderEXT m_FragShader{};
// ---- RenderGraph 资源句柄 ----
RG::TextureHandle m_Backbuffer{};
RG::TextureHandle m_Depth{};
vk::ShaderEXT m_VertShader;
vk::ShaderEXT m_FragShader;
// ---- 当帧绑定(Render() 期间有效,供 pass 回调读取)----
ECS::Scene* m_BoundScene = nullptr;
Assets::AssetManager* m_BoundAssets = nullptr;
vk::Extent2D m_Extent;
vk::Format m_Format;
static constexpr u32 kMaxFramesInFlight = 2;
vk::Extent2D m_Extent{};
u32 m_CurrentFrame = 0;
// 相机
glm::vec3 m_CameraPos = glm::vec3(0.0f, 0.0f, 7.0f);
f32 m_CameraYaw = -90.0f; // 朝向 -Z
f32 m_CameraPitch = 0.0f;
f32 m_CameraSpeed = 2.5f;
f32 m_MouseSensitivity = 0.1f;
f32 m_DeltaTime = 0.016f;
f32 m_LastFrameTime = 0.0f;
std::chrono::steady_clock::time_point m_StartTime;
};
} // namespace Engine