使用 Vulkan 1.4 现代路径初始化引擎骨架: - 用 Shader Object (VK_EXT_shader_object) 替代传统 VkPipeline - 用 Dynamic Rendering 替代 RenderPass/Framebuffer - 用 Synchronization2 管理 barrier 核心模块: - Window:GLFW 封装,GLFW_NO_API 模式,兼容 Wayland - Log:spdlog 封装 - Types:u32/u64/f32 类型别名 Vulkan 后端: - Device:Instance、PhysicalDevice、LogicalDevice、Queue 及 feature 查询 - Swapchain:Image、ImageView、DepthBuffer、Recreate - ShaderManager:SPIR-V 加载与 ShaderEXT 创建 - CommandManager:CommandPool 与主 CommandBuffer - SyncManager:per-frame Fence 与 ImageAvailable semaphore,per-image RenderFinished semaphore,2 frames in flight - MemoryAllocator:内存子分配器,256MB block,persistent mapping - Buffer:VertexBuffer、IndexBuffer、UniformBuffer 封装 - UniformBuffer:每帧上传 MVP 矩阵 - DescriptorManager:DescriptorSetLayout、DescriptorPool、DescriptorSet 及更新 Renderer: - 协调所有子系统 - 绘制每面不同颜色的旋转 3D 立方体 - 启用 depth test,MVP 矩阵由 GLM 计算 构建: - CMake 组织 Engine 静态库与 App 可执行文件 - glfw、glm、spdlog 通过 add_subdirectory 引入
64 lines
1.9 KiB
C++
64 lines
1.9 KiB
C++
//
|
|
// Created by atdunbg on 2026/9/20.
|
|
//
|
|
|
|
|
|
#include <Engine/Vulkan/SyncManager.h>
|
|
#include <Engine/Vulkan/Device.h>
|
|
#include <Engine/Core/Log.h>
|
|
|
|
#include <limits>
|
|
|
|
namespace Engine {
|
|
|
|
SyncManager::SyncManager(Device& device, u32 maxFramesInFlight, u32 imageCount)
|
|
: m_Device(device)
|
|
{
|
|
vk::SemaphoreCreateInfo semInfo;
|
|
|
|
// 每帧一个 ImageAvailable
|
|
m_ImageAvailable.resize(maxFramesInFlight);
|
|
for (auto& sem : m_ImageAvailable) {
|
|
sem = m_Device.GetDevice().createSemaphore(semInfo);
|
|
}
|
|
|
|
// 每张交换链 image 一个 RenderFinished
|
|
m_RenderFinished.resize(imageCount);
|
|
for (auto& sem : m_RenderFinished) {
|
|
sem = m_Device.GetDevice().createSemaphore(semInfo);
|
|
}
|
|
|
|
// 每帧一个 Fence,初始 signaled
|
|
vk::FenceCreateInfo fenceInfo;
|
|
fenceInfo.setFlags(vk::FenceCreateFlagBits::eSignaled);
|
|
m_FrameFences.resize(maxFramesInFlight);
|
|
for (auto& fence : m_FrameFences) {
|
|
fence = m_Device.GetDevice().createFence(fenceInfo);
|
|
}
|
|
|
|
ENGINE_INFO("SyncManager created ({} frames, {} images)",
|
|
maxFramesInFlight, imageCount);
|
|
}
|
|
|
|
SyncManager::~SyncManager()
|
|
{
|
|
const auto& vkDevice = m_Device.GetDevice();
|
|
for (auto f : m_FrameFences) vkDevice.destroyFence(f);
|
|
for (auto s : m_ImageAvailable) vkDevice.destroySemaphore(s);
|
|
for (auto s : m_RenderFinished) vkDevice.destroySemaphore(s);
|
|
}
|
|
|
|
void SyncManager::WaitFence(u32 frameIndex)
|
|
{
|
|
auto result = m_Device.GetDevice().waitForFences(
|
|
m_FrameFences[frameIndex], VK_TRUE, std::numeric_limits<u64>::max());
|
|
if (result != vk::Result::eSuccess) {
|
|
ENGINE_ERROR("waitForFences failed");
|
|
}
|
|
}
|
|
|
|
void SyncManager::ResetFence(u32 frameIndex)
|
|
{
|
|
m_Device.GetDevice().resetFences(m_FrameFences[frameIndex]);
|
|
}
|
|
} // namespace Engine
|