feat: 搭建 Vulkan 1.4 渲染器骨架,绘制旋转 3D 立方体
使用 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 引入
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
//
|
||||
// Created by atdunbg on 2026/9/20.
|
||||
//
|
||||
|
||||
#ifndef HELLOVULKAN_LOG_H
|
||||
#define HELLOVULKAN_LOG_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <spdlog/spdlog.h>
|
||||
|
||||
namespace Engine {
|
||||
|
||||
#define ENGINE_TRACE(...) ::spdlog::trace(__VA_ARGS__)
|
||||
#define ENGINE_INFO(...) ::spdlog::info(__VA_ARGS__)
|
||||
#define ENGINE_WARN(...) ::spdlog::warn(__VA_ARGS__)
|
||||
#define ENGINE_ERROR(...) ::spdlog::error(__VA_ARGS__)
|
||||
#define ENGINE_FATAL(...) ::spdlog::critical(__VA_ARGS__)
|
||||
|
||||
} // namespace Engine
|
||||
|
||||
#endif //HELLOVULKAN_LOG_H
|
||||
@@ -0,0 +1,45 @@
|
||||
//
|
||||
// Created by atdunbg on 2026/9/20.
|
||||
//
|
||||
|
||||
#ifndef HELLOVULKAN_TYPES_H
|
||||
#define HELLOVULKAN_TYPES_H
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
namespace Engine {
|
||||
|
||||
using u8 = uint8_t;
|
||||
using u16 = uint16_t;
|
||||
using u32 = uint32_t;
|
||||
using u64 = uint64_t;
|
||||
|
||||
using i8 = int8_t;
|
||||
using i16 = int16_t;
|
||||
using i32 = int32_t;
|
||||
using i64 = int64_t;
|
||||
|
||||
using f32 = float;
|
||||
using f64 = double;
|
||||
|
||||
template<typename T>
|
||||
using Scope = std::unique_ptr<T>;
|
||||
|
||||
template<typename T>
|
||||
using Ref = std::shared_ptr<T>;
|
||||
|
||||
template<typename T, typename... Args>
|
||||
Scope<T> CreateScope(Args&&... args) {
|
||||
return std::make_unique<T>(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template<typename T, typename... Args>
|
||||
Ref<T> CreateRef(Args&&... args) {
|
||||
return std::make_shared<T>(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
} // namespace Engine
|
||||
|
||||
#endif //HELLOVULKAN_TYPES_H
|
||||
@@ -0,0 +1,51 @@
|
||||
//
|
||||
// Created by atdunbg on 2026/9/20.
|
||||
//
|
||||
|
||||
#ifndef HELLOVULKAN_WINDOW_H
|
||||
#define HELLOVULKAN_WINDOW_H
|
||||
|
||||
|
||||
#include <vulkan/vulkan.hpp>
|
||||
#include <string>
|
||||
#include <functional>
|
||||
|
||||
#include "Types.h"
|
||||
|
||||
struct GLFWwindow;
|
||||
|
||||
namespace Engine {
|
||||
|
||||
class Window {
|
||||
public:
|
||||
Window(const std::string& title, u32 width, u32 height);
|
||||
~Window();
|
||||
|
||||
Window(const Window&) = delete;
|
||||
Window& operator=(const Window&) = delete;
|
||||
|
||||
bool ShouldClose() const;
|
||||
void PollEvents();
|
||||
|
||||
vk::SurfaceKHR CreateSurface(vk::Instance instance);
|
||||
void DestroySurface(vk::Instance instance, vk::SurfaceKHR surface);
|
||||
|
||||
u32 GetWidth() const { return m_Width; }
|
||||
u32 GetHeight() const { return m_Height; }
|
||||
|
||||
GLFWwindow* GetHandle() const { return m_Window; }
|
||||
|
||||
// 需要的 Vulkan 扩展(GLFW 提供)
|
||||
static std::vector<const char*> GetRequiredExtensions();
|
||||
|
||||
private:
|
||||
GLFWwindow* m_Window = nullptr;
|
||||
u32 m_Width;
|
||||
u32 m_Height;
|
||||
std::string m_Title;
|
||||
};
|
||||
|
||||
} // namespace Engine
|
||||
|
||||
|
||||
#endif //HELLOVULKAN_WINDOW_H
|
||||
@@ -0,0 +1,74 @@
|
||||
//
|
||||
// Created by atdunbg on 2026/9/20.
|
||||
//
|
||||
|
||||
#ifndef HELLOVULKAN_RENDERER_H
|
||||
#define HELLOVULKAN_RENDERER_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Engine/Core/Types.h>
|
||||
#include <vulkan/vulkan.hpp>
|
||||
#include <chrono>
|
||||
|
||||
namespace Engine {
|
||||
|
||||
class Window;
|
||||
class Device;
|
||||
class MemoryAllocator;
|
||||
class DescriptorManager;
|
||||
class ShaderManager;
|
||||
class Swapchain;
|
||||
class CommandManager;
|
||||
class SyncManager;
|
||||
class Buffer;
|
||||
class UniformBuffer;
|
||||
|
||||
class Renderer {
|
||||
public:
|
||||
Renderer(Window& window);
|
||||
~Renderer();
|
||||
|
||||
Renderer(const Renderer&) = delete;
|
||||
Renderer& operator=(const Renderer&) = delete;
|
||||
|
||||
void Render();
|
||||
|
||||
private:
|
||||
void RecordCommands(vk::CommandBuffer cmd, u32 imageIndex);
|
||||
void TransitionImageLayout(vk::CommandBuffer cmd, vk::Image image,
|
||||
vk::ImageLayout oldLayout, vk::ImageLayout newLayout);
|
||||
|
||||
Window& m_Window;
|
||||
|
||||
Scope<Device> m_Device;
|
||||
Scope<MemoryAllocator> m_Allocator;
|
||||
Scope<DescriptorManager> m_DescriptorManager;
|
||||
Scope<ShaderManager> m_ShaderManager;
|
||||
Scope<Swapchain> m_Swapchain;
|
||||
Scope<SyncManager> m_SyncManager;
|
||||
Scope<CommandManager> m_CommandManager;
|
||||
|
||||
Scope<Buffer> m_VertexBuffer;
|
||||
Scope<Buffer> m_IndexBuffer;
|
||||
Scope<UniformBuffer> m_UniformBuffer;
|
||||
|
||||
vk::DescriptorSetLayout m_DescriptorSetLayout;
|
||||
vk::PipelineLayout m_PipelineLayout;
|
||||
vk::DescriptorSet m_DescriptorSet;
|
||||
|
||||
vk::ShaderEXT m_VertShader;
|
||||
vk::ShaderEXT m_FragShader;
|
||||
|
||||
vk::Extent2D m_Extent;
|
||||
vk::Format m_Format;
|
||||
|
||||
static constexpr u32 kMaxFramesInFlight = 2;
|
||||
u32 m_CurrentFrame = 0;
|
||||
|
||||
std::chrono::steady_clock::time_point m_StartTime;
|
||||
};
|
||||
|
||||
} // namespace Engine
|
||||
|
||||
#endif //HELLOVULKAN_RENDERER_H
|
||||
@@ -0,0 +1,47 @@
|
||||
//
|
||||
// Created by atdunbg on 2026/9/20.
|
||||
//
|
||||
|
||||
#ifndef HELLOVULKAN_BUFFER_H
|
||||
#define HELLOVULKAN_BUFFER_H
|
||||
|
||||
|
||||
#include <vulkan/vulkan.hpp>
|
||||
|
||||
namespace Engine {
|
||||
|
||||
class Device;
|
||||
class MemoryAllocator;
|
||||
|
||||
class Buffer {
|
||||
public:
|
||||
Buffer(Device& device, MemoryAllocator& allocator,
|
||||
vk::DeviceSize size, vk::BufferUsageFlags usage,
|
||||
vk::MemoryPropertyFlags memProps);
|
||||
~Buffer();
|
||||
|
||||
Buffer(const Buffer&) = delete;
|
||||
Buffer& operator=(const Buffer&) = delete;
|
||||
|
||||
vk::Buffer Get() const { return m_Buffer; }
|
||||
vk::DeviceSize GetSize() const { return m_Size; }
|
||||
|
||||
// 只有 HOST_VISIBLE 的 Buffer 能调
|
||||
void Upload(const void* data, vk::DeviceSize size, vk::DeviceSize offset = 0);
|
||||
|
||||
private:
|
||||
Device& m_Device;
|
||||
vk::Buffer m_Buffer;
|
||||
vk::DeviceSize m_Size;
|
||||
|
||||
vk::DeviceMemory m_Memory;
|
||||
vk::DeviceSize m_Offset;
|
||||
|
||||
vk::DeviceSize m_BlockSize; // 所属内存块的总大小
|
||||
|
||||
void* m_MappedPtr = nullptr;
|
||||
};
|
||||
|
||||
} // namespace Engine
|
||||
|
||||
#endif //HELLOVULKAN_BUFFER_H
|
||||
@@ -0,0 +1,38 @@
|
||||
//
|
||||
// Created by atdunbg on 2026/9/20.
|
||||
//
|
||||
|
||||
#ifndef HELLOVULKAN_COMMANDMANAGER_H
|
||||
#define HELLOVULKAN_COMMANDMANAGER_H
|
||||
|
||||
#include <vulkan/vulkan.hpp>
|
||||
|
||||
namespace Engine {
|
||||
|
||||
class Device;
|
||||
|
||||
class CommandManager {
|
||||
public:
|
||||
CommandManager(Device& device);
|
||||
~CommandManager();
|
||||
|
||||
CommandManager(const CommandManager&) = delete;
|
||||
CommandManager& operator=(const CommandManager&) = delete;
|
||||
|
||||
// 开始录制
|
||||
vk::CommandBuffer BeginFrame();
|
||||
|
||||
// 结束录制
|
||||
void EndFrame();
|
||||
|
||||
vk::CommandBuffer GetBuffer() const { return m_Buffer; }
|
||||
|
||||
private:
|
||||
Device& m_Device;
|
||||
vk::CommandPool m_Pool;
|
||||
vk::CommandBuffer m_Buffer;
|
||||
};
|
||||
|
||||
} // namespace Engine
|
||||
|
||||
#endif //HELLOVULKAN_COMMANDMANAGER_H
|
||||
@@ -0,0 +1,46 @@
|
||||
//
|
||||
// Created by atdunbg on 2026/9/20.
|
||||
//
|
||||
|
||||
#ifndef HELLOVULKAN_DESCRIPTORMANAGER_H
|
||||
#define HELLOVULKAN_DESCRIPTORMANAGER_H
|
||||
|
||||
|
||||
#include <Engine/Core/Types.h>
|
||||
#include <vulkan/vulkan.hpp>
|
||||
|
||||
namespace Engine {
|
||||
|
||||
class Device;
|
||||
|
||||
class DescriptorManager {
|
||||
public:
|
||||
DescriptorManager(Device& device);
|
||||
~DescriptorManager();
|
||||
|
||||
DescriptorManager(const DescriptorManager&) = delete;
|
||||
DescriptorManager& operator=(const DescriptorManager&) = delete;
|
||||
|
||||
// 创建一个描述符布局:一个 binding,类型是 Uniform Buffer
|
||||
vk::DescriptorSetLayout CreateUniformBufferLayout(u32 binding);
|
||||
|
||||
vk::PipelineLayout CreatePipelineLayout(vk::DescriptorSetLayout layout);
|
||||
|
||||
// 根据布局分配一个描述符集
|
||||
vk::DescriptorSet AllocateDescriptorSet(vk::DescriptorSetLayout layout);
|
||||
|
||||
// 把 Buffer 绑到描述符集的某个 binding
|
||||
void UpdateUniformBuffer(vk::DescriptorSet set, u32 binding,
|
||||
vk::Buffer buffer, u64 size);
|
||||
|
||||
|
||||
private:
|
||||
Device& m_Device;
|
||||
vk::DescriptorPool m_Pool;
|
||||
|
||||
static constexpr u32 kMaxSets = 1000;
|
||||
};
|
||||
|
||||
} // namespace Engine
|
||||
|
||||
#endif //HELLOVULKAN_DESCRIPTORMANAGER_H
|
||||
@@ -0,0 +1,83 @@
|
||||
//
|
||||
// Created by atdunbg on 2026/9/20.
|
||||
//
|
||||
|
||||
#ifndef HELLOVULKAN_DEVICE_H
|
||||
#define HELLOVULKAN_DEVICE_H
|
||||
|
||||
|
||||
#include <vulkan/vulkan.hpp>
|
||||
#include <vector>
|
||||
|
||||
namespace Engine {
|
||||
|
||||
class Window;
|
||||
|
||||
class Device {
|
||||
public:
|
||||
Device(Window& window);
|
||||
~Device();
|
||||
|
||||
Device(const Device&) = delete;
|
||||
Device& operator=(const Device&) = delete;
|
||||
|
||||
vk::Instance GetInstance() const { return m_Instance; }
|
||||
vk::PhysicalDevice GetPhysicalDevice() const { return m_PhysicalDevice; }
|
||||
vk::Device GetDevice() const { return m_Device; }
|
||||
vk::SurfaceKHR GetSurface() const { return m_Surface; }
|
||||
|
||||
vk::Queue GetGraphicsQueue() const { return m_GraphicsQueue; }
|
||||
vk::Queue GetPresentQueue() const { return m_PresentQueue; }
|
||||
|
||||
uint32_t GetGraphicsFamily() const { return m_GraphicsFamily; }
|
||||
uint32_t GetPresentFamily() const { return m_PresentFamily; }
|
||||
|
||||
uint32_t FindMemoryType(uint32_t typeFilter, vk::MemoryPropertyFlags props) const;
|
||||
|
||||
// 1.4 特性查询
|
||||
bool IsDynamicRenderingSupported() const { return m_DynamicRenderingSupported; }
|
||||
bool IsShaderObjectSupported() const { return m_ShaderObjectSupported; }
|
||||
bool IsSynchronization2Supported() const { return m_Synchronization2Supported; }
|
||||
|
||||
private:
|
||||
void CreateInstance();
|
||||
void SetupDebugMessenger();
|
||||
void CreateSurface(Window& window);
|
||||
void PickPhysicalDevice();
|
||||
void CreateLogicalDevice();
|
||||
|
||||
bool IsDeviceSuitable(vk::PhysicalDevice device);
|
||||
bool CheckValidationLayerSupport();
|
||||
|
||||
vk::Instance m_Instance;
|
||||
vk::DebugUtilsMessengerEXT m_DebugMessenger;
|
||||
vk::SurfaceKHR m_Surface;
|
||||
vk::PhysicalDevice m_PhysicalDevice;
|
||||
vk::Device m_Device;
|
||||
|
||||
vk::Queue m_GraphicsQueue;
|
||||
vk::Queue m_PresentQueue;
|
||||
|
||||
uint32_t m_GraphicsFamily = 0;
|
||||
uint32_t m_PresentFamily = 0;
|
||||
|
||||
vk::PhysicalDeviceMemoryProperties m_MemoryProperties;
|
||||
|
||||
// 1.4 特性标志
|
||||
bool m_DynamicRenderingSupported = false;
|
||||
bool m_ShaderObjectSupported = false;
|
||||
bool m_Synchronization2Supported = false;
|
||||
|
||||
std::vector<const char*> m_ValidationLayers = { "VK_LAYER_KHRONOS_validation" };
|
||||
std::vector<const char*> m_DeviceExtensions = { VK_KHR_SWAPCHAIN_EXTENSION_NAME };
|
||||
|
||||
#ifdef NDEBUG
|
||||
static constexpr bool kEnableValidation = false;
|
||||
#else
|
||||
static constexpr bool kEnableValidation = true;
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace Engine
|
||||
|
||||
#endif //HELLOVULKAN_DEVICE_H
|
||||
@@ -0,0 +1,50 @@
|
||||
//
|
||||
// Created by atdunbg on 2026/9/20.
|
||||
//
|
||||
|
||||
#ifndef HELLOVULKAN_MEMORYALLOCATOR_H
|
||||
#define HELLOVULKAN_MEMORYALLOCATOR_H
|
||||
|
||||
|
||||
#include <vulkan/vulkan.hpp>
|
||||
#include <array>
|
||||
#include <vector>
|
||||
|
||||
namespace Engine {
|
||||
|
||||
class Device;
|
||||
|
||||
class MemoryAllocator {
|
||||
public:
|
||||
MemoryAllocator(Device& device);
|
||||
~MemoryAllocator();
|
||||
|
||||
MemoryAllocator(const MemoryAllocator&) = delete;
|
||||
MemoryAllocator& operator=(const MemoryAllocator&) = delete;
|
||||
|
||||
struct Allocation {
|
||||
vk::DeviceMemory Memory;
|
||||
vk::DeviceSize Offset;
|
||||
vk::DeviceSize Size;
|
||||
void* MappedPtr; // HOST_VISIBLE 时才有
|
||||
};
|
||||
|
||||
Allocation Allocate(vk::MemoryRequirements reqs, vk::MemoryPropertyFlags props);
|
||||
|
||||
private:
|
||||
struct Block {
|
||||
vk::DeviceMemory Memory;
|
||||
vk::DeviceSize Size;
|
||||
vk::DeviceSize Used;
|
||||
void* MappedPtr = nullptr;
|
||||
bool IsMapped = false;
|
||||
};
|
||||
|
||||
Device& m_Device;
|
||||
std::array<std::vector<Block>, VK_MAX_MEMORY_TYPES> m_Blocks;
|
||||
vk::DeviceSize m_DefaultBlockSize = 256ull * 1024 * 1024; // 256 MB
|
||||
};
|
||||
|
||||
} // namespace Engine
|
||||
|
||||
#endif //HELLOVULKAN_MEMORYALLOCATOR_H
|
||||
@@ -0,0 +1,8 @@
|
||||
//
|
||||
// Created by atdunbg on 2026/9/20.
|
||||
//
|
||||
|
||||
#ifndef HELLOVULKAN_PIPELINE_H
|
||||
#define HELLOVULKAN_PIPELINE_H
|
||||
|
||||
#endif //HELLOVULKAN_PIPELINE_H
|
||||
@@ -0,0 +1,52 @@
|
||||
//
|
||||
// Created by atdunbg on 2026/9/20.
|
||||
//
|
||||
|
||||
#ifndef HELLOVULKAN_SHADERMANAGER_H
|
||||
#define HELLOVULKAN_SHADERMANAGER_H
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Engine/Core/Types.h>
|
||||
#include <vulkan/vulkan.hpp>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace Engine {
|
||||
|
||||
class Device;
|
||||
|
||||
struct ShaderObject {
|
||||
vk::ShaderEXT Handle;
|
||||
vk::ShaderStageFlagBits Stage;
|
||||
};
|
||||
|
||||
class ShaderManager {
|
||||
public:
|
||||
ShaderManager(Device& device);
|
||||
~ShaderManager();
|
||||
|
||||
ShaderManager(const ShaderManager&) = delete;
|
||||
ShaderManager& operator=(const ShaderManager&) = delete;
|
||||
|
||||
// layout 可选:为 nullptr 时不使用描述符
|
||||
ShaderObject CreateFromFile(const std::string& spvPath,
|
||||
vk::ShaderStageFlagBits stage,
|
||||
vk::DescriptorSetLayout layout = nullptr);
|
||||
|
||||
ShaderObject CreateFromSPIRV(const std::vector<u32>& spirv,
|
||||
vk::ShaderStageFlagBits stage,
|
||||
vk::DescriptorSetLayout layout = nullptr);
|
||||
|
||||
void Destroy(const ShaderObject& shader);
|
||||
|
||||
private:
|
||||
std::vector<u32> ReadSPIRV(const std::string& path);
|
||||
|
||||
Device& m_Device;
|
||||
};
|
||||
|
||||
} // namespace Engine
|
||||
|
||||
#endif //HELLOVULKAN_SHADERMANAGER_H
|
||||
@@ -0,0 +1,73 @@
|
||||
//
|
||||
// Created by atdunbg on 2026/9/20.
|
||||
//
|
||||
|
||||
#ifndef HELLOVULKAN_SWAPCHAIN_H
|
||||
#define HELLOVULKAN_SWAPCHAIN_H
|
||||
|
||||
#include <vulkan/vulkan.hpp>
|
||||
#include <vector>
|
||||
|
||||
#include "MemoryAllocator.h"
|
||||
#include "Engine/Core/Types.h"
|
||||
|
||||
namespace Engine
|
||||
{
|
||||
class Device;
|
||||
class Window;
|
||||
|
||||
class Swapchain
|
||||
{
|
||||
public:
|
||||
Swapchain(Device& device, MemoryAllocator& allocator, Window& window);
|
||||
~Swapchain();
|
||||
|
||||
Swapchain(const Swapchain&) = delete;
|
||||
Swapchain& operator=(const Swapchain&) = delete;
|
||||
|
||||
vk::SwapchainKHR Get() const { return m_Swapchain; }
|
||||
vk::Format GetFormat() const { return m_Format; }
|
||||
vk::Extent2D GetExtent() const { return m_Extent; }
|
||||
uint32_t GetImageCount() const { return static_cast<u32>(m_Images.size()); }
|
||||
|
||||
const std::vector<vk::Image>& GetImages() const { return m_Images; }
|
||||
const std::vector<vk::ImageView>& GetImageViews() const { return m_ImageViews; }
|
||||
|
||||
vk::ImageView GetDepthImageView() const { return m_DepthImageView; }
|
||||
vk::Format GetDepthFormat() const { return m_DepthFormat; }
|
||||
vk::Image GetDepthImage() const { return m_DepthImage; }
|
||||
|
||||
void Recreate(Window& window);
|
||||
|
||||
private:
|
||||
void Create(Window& window);
|
||||
void Destroy();
|
||||
|
||||
vk::SurfaceFormatKHR ChooseSurfaceFormat(const std::vector<vk::SurfaceFormatKHR>& formats);
|
||||
vk::PresentModeKHR ChoosePresentMode(const std::vector<vk::PresentModeKHR>& modes);
|
||||
vk::Extent2D ChooseExtent(const vk::SurfaceCapabilitiesKHR& caps, Window& window);
|
||||
|
||||
void CreateDepthResources();
|
||||
void DestroyDepthResources();
|
||||
vk::Format FindDepthFormat();
|
||||
|
||||
|
||||
Device& m_Device;
|
||||
|
||||
vk::SwapchainKHR m_Swapchain;
|
||||
std::vector<vk::Image> m_Images;
|
||||
std::vector<vk::ImageView> m_ImageViews;
|
||||
|
||||
vk::Image m_DepthImage;
|
||||
vk::DeviceMemory m_DepthMemory;
|
||||
vk::ImageView m_DepthImageView;
|
||||
vk::Format m_DepthFormat;
|
||||
|
||||
MemoryAllocator& m_Allocator;
|
||||
|
||||
vk::Format m_Format;
|
||||
vk::Extent2D m_Extent;
|
||||
};
|
||||
} // namespace Engine
|
||||
|
||||
#endif //HELLOVULKAN_SWAPCHAIN_H
|
||||
@@ -0,0 +1,50 @@
|
||||
//
|
||||
// Created by atdunbg on 2026/9/20.
|
||||
//
|
||||
|
||||
#ifndef HELLOVULKAN_SYNCMANAGER_H
|
||||
#define HELLOVULKAN_SYNCMANAGER_H
|
||||
|
||||
|
||||
#include <vulkan/vulkan.hpp>
|
||||
#include <vector>
|
||||
|
||||
#include "Engine/Core/Types.h"
|
||||
|
||||
namespace Engine {
|
||||
|
||||
class Device;
|
||||
|
||||
class SyncManager {
|
||||
public:
|
||||
SyncManager(Device& device, u32 maxFramesInFlight, u32 imageCount);
|
||||
~SyncManager();
|
||||
|
||||
SyncManager(const SyncManager&) = delete;
|
||||
SyncManager& operator=(const SyncManager&) = delete;
|
||||
|
||||
// 每帧一个:acquire 完成时 signal
|
||||
vk::Semaphore GetImageAvailable(u32 imageIndex) const { return m_ImageAvailable[imageIndex]; }
|
||||
|
||||
// 每张交换链 image 一个:渲染完成时 signal
|
||||
vk::Semaphore GetRenderFinished(u32 imageIndex) const {
|
||||
return m_RenderFinished[imageIndex];
|
||||
}
|
||||
|
||||
// 每帧一个:GPU 渲染完成时 signal
|
||||
vk::Fence GetFrameFence(u32 frameIndex) const { return m_FrameFences[frameIndex]; }
|
||||
|
||||
// 等待并重置这一帧的 Fence
|
||||
void WaitFence(u32 frameIndex); // 只等,不 reset
|
||||
void ResetFence(u32 frameIndex); // 只 reset
|
||||
|
||||
private:
|
||||
Device& m_Device;
|
||||
std::vector<vk::Semaphore> m_ImageAvailable;
|
||||
std::vector<vk::Semaphore> m_RenderFinished;
|
||||
std::vector<vk::Fence> m_FrameFences;
|
||||
};
|
||||
|
||||
} // namespace Engine
|
||||
|
||||
#endif //HELLOVULKAN_SYNCMANAGER_H
|
||||
@@ -0,0 +1,39 @@
|
||||
//
|
||||
// Created by atdunbg on 2026/9/20.
|
||||
//
|
||||
|
||||
#ifndef HELLOVULKAN_UNIFORMBUFFER_H
|
||||
#define HELLOVULKAN_UNIFORMBUFFER_H
|
||||
|
||||
|
||||
#include <Engine/Core/Types.h>
|
||||
#include <Engine/Vulkan/Buffer.h>
|
||||
#include <vulkan/vulkan.hpp>
|
||||
|
||||
namespace Engine {
|
||||
|
||||
class Device;
|
||||
class MemoryAllocator;
|
||||
|
||||
class UniformBuffer {
|
||||
public:
|
||||
UniformBuffer(Device& device, MemoryAllocator& allocator, u64 size);
|
||||
~UniformBuffer();
|
||||
|
||||
UniformBuffer(const UniformBuffer&) = delete;
|
||||
UniformBuffer& operator=(const UniformBuffer&) = delete;
|
||||
|
||||
vk::Buffer Get() const { return m_Buffer->Get(); }
|
||||
u64 GetSize() const { return m_Size; }
|
||||
|
||||
// 每帧更新数据
|
||||
void Update(const void* data, u64 size);
|
||||
|
||||
private:
|
||||
Scope<Buffer> m_Buffer;
|
||||
u64 m_Size;
|
||||
};
|
||||
|
||||
} // namespace Engine
|
||||
|
||||
#endif //HELLOVULKAN_UNIFORMBUFFER_H
|
||||
Reference in New Issue
Block a user