// // Created by atdunbg on 2026/9/20. // // ShaderManager:shader object(VK_EXT_shader_object)创建工厂。 // // 生命周期模型(UE FShaderResource / TShaderRef 语义):Create* 返回 // 引用计数句柄 ShaderRef,拷贝 = 共享所有权,最后一个引用析构时自动 // 销毁 VkShaderEXT——持有方零清理代码,"新 pass 忘销毁"整类 bug 被 // 机制消灭(曾因手工管理漏销毁退出时报 VUID-05137 泄漏)。 // // 唯一约束:ShaderRef 不得比 Device 活得久(引擎内所有持有方都在 // Renderer 子树内、先于 Device 析构,天然满足;勿存进静态/长寿命容器)。 // #ifndef HELLOVULKAN_SHADERMANAGER_H #define HELLOVULKAN_SHADERMANAGER_H #pragma once #include #include #include #include #include namespace Engine { class Device; class ShaderManager { public: // ---- 引用计数句柄 ---- // 空句柄(创建失败)可用 operator bool 判定,此时 GetHandle() // 返回空 handle(bind 前由调用方判空跳过) class ShaderRef { public: ShaderRef() = default; explicit operator bool() const { return m_Entry != nullptr; } vk::ShaderEXT GetHandle() const { return m_Entry ? m_Entry->handle : vk::ShaderEXT{}; } vk::ShaderStageFlagBits GetStage() const { return m_Entry->stage; } private: friend class ShaderManager; struct Entry { vk::ShaderEXT handle{}; vk::ShaderStageFlagBits stage{}; Device* device = nullptr; ~Entry(); // cpp 定义:销毁 VkShaderEXT(需 Device 完整类型) }; explicit ShaderRef(std::shared_ptr e) : m_Entry(std::move(e)) {} std::shared_ptr m_Entry; }; explicit ShaderManager(Device& device); ~ShaderManager() = default; // shader 随引用计数自动释放 ShaderManager(const ShaderManager&) = delete; ShaderManager& operator=(const ShaderManager&) = delete; ShaderRef CreateFromFile(const std::string& spvPath, vk::ShaderStageFlagBits stage, const std::vector& layouts = {}, u32 pushConstantSize = 0); ShaderRef CreateFromSPIRV(const std::vector& spirv, vk::ShaderStageFlagBits stage, const std::vector& layouts = {}, u32 pushConstantSize = 0) const; private: static std::vector ReadSPIRV(const std::string& path); Device& m_Device; }; } // namespace Engine #endif //HELLOVULKAN_SHADERMANAGER_H