From ecdc23ee1905001cd4c9e26d216ebd4e0265280d Mon Sep 17 00:00:00 2001 From: nanako <469449812@qq.com> Date: Wed, 31 Dec 2025 02:02:01 +0800 Subject: [PATCH] =?UTF-8?q?=E8=BF=81=E7=A7=BB=E5=88=B0vulkan=20hpp?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/06-phase3-widget-system.md | 2 +- docs/07-phase4-debugger.md | 4 +- docs/项目蓝图.md | 2 +- plans/vulkan-hpp-migration-plan.md | 317 ++++++++++++++ src/core/assert.hpp | 2 +- src/core/object.hpp | 14 + src/debug/gpu_profiler.cpp | 135 +++--- src/debug/gpu_profiler.hpp | 31 +- src/render/batch.cpp | 291 +++++++------ src/render/batch.hpp | 49 ++- src/render/command_buffer.cpp | 479 ++++++++++----------- src/render/command_buffer.hpp | 139 +++--- src/render/frame_sync.cpp | 209 +++++---- src/render/frame_sync.hpp | 32 +- src/render/pipeline.cpp | 428 +++++++++---------- src/render/pipeline.hpp | 162 +++---- src/render/render_pass.cpp | 158 ++++--- src/render/render_pass.hpp | 113 +++-- src/render/renderer.cpp | 367 ++++++++-------- src/render/renderer.hpp | 45 +- src/render/swapchain.cpp | 215 +++++----- src/render/swapchain.hpp | 63 +-- src/render/vulkan_device.cpp | 171 ++++---- src/render/vulkan_device.hpp | 80 ++-- src/render/vulkan_instance.cpp | 294 ++++++------- src/render/vulkan_instance.hpp | 30 +- src/render/vulkan_types.hpp | 268 +++++------- src/resource/CMakeLists.txt | 2 +- src/resource/allocator.cpp | 86 ++-- src/resource/allocator.hpp | 50 +-- src/resource/buffer.cpp | 71 ++- src/resource/buffer.hpp | 26 +- src/resource/descriptor_pool.cpp | 134 +++--- src/resource/descriptor_pool.hpp | 68 +-- src/resource/resource_loader.cpp | 16 +- src/resource/resource_manager.cpp | 36 +- src/resource/resource_types.hpp | 665 ++++++++++++----------------- src/resource/sampler.cpp | 63 +-- src/resource/sampler.hpp | 30 +- src/resource/texture.cpp | 191 ++++----- src/resource/texture.hpp | 40 +- src/resource/texture_view.cpp | 52 +-- src/resource/texture_view.hpp | 40 +- src/shader/CMakeLists.txt | 2 +- src/shader/shader_cache.cpp | 8 +- src/shader/shader_module.cpp | 89 ++-- src/shader/shader_module.hpp | 46 +- src/shader/shader_program.cpp | 32 +- src/shader/shader_program.hpp | 20 +- src/text/font.cpp | 36 +- src/text/font.hpp | 10 +- src/text/font_manager.cpp | 38 +- src/text/glyph_atlas.cpp | 18 +- src/text/glyph_cache.cpp | 6 +- src/text/text_shaper.cpp | 6 +- tests/core/test_logger.cpp | 14 +- 56 files changed, 2943 insertions(+), 3052 deletions(-) create mode 100644 plans/vulkan-hpp-migration-plan.md diff --git a/docs/06-phase3-widget-system.md b/docs/06-phase3-widget-system.md index 53d661e..3de887f 100644 --- a/docs/06-phase3-widget-system.md +++ b/docs/06-phase3-widget-system.md @@ -3081,7 +3081,7 @@ public: // 打印性能统计 if (frame_time > 16000) { // 超过 16ms - log_warning("Frame took {}ms, {} widgets, {} dirty", + MILAI_LOG_WARN("Frame took {}ms, {} widgets, {} dirty", frame_time / 1000.0, widget_count_, dirty_count_); } } diff --git a/docs/07-phase4-debugger.md b/docs/07-phase4-debugger.md index c80ca44..edb3c65 100644 --- a/docs/07-phase4-debugger.md +++ b/docs/07-phase4-debugger.md @@ -554,7 +554,7 @@ void perf_overlay::paint(render_context& ctx) { ```cpp // 监听热重载事件 shader_hot_reloader::instance().on_before_reload = [](const auto& path) { - log_info("Reloading shader: {}", path.string()); + MILAI_LOG_INFO("Reloading shader: {}", path.string()); }; shader_hot_reloader::instance().on_after_reload = [](const auto& path) { @@ -568,7 +568,7 @@ shader_hot_reloader::instance().on_after_reload = [](const auto& path) { }; shader_hot_reloader::instance().on_reload_failed = [](const auto& path, const auto& error) { - log_error("Failed to reload shader {}: {}", path.string(), error); + MILAI_LOG_ERROR("Failed to reload shader {}: {}", path.string(), error); // 显示错误通知 notification::show_error("Shader reload failed", error); diff --git a/docs/项目蓝图.md b/docs/项目蓝图.md index dc44c80..9c8a914 100644 --- a/docs/项目蓝图.md +++ b/docs/项目蓝图.md @@ -324,7 +324,7 @@ void handle_vulkan_error(VkResult result, const char* file, int line) { break; default: // 记录错误并抛出异常 - log_error("Vulkan error {} at {}:{}", result, file, line); + MILAI_LOG_ERROR("Vulkan error {} at {}:{}", result, file, line); throw vulkan_exception(result); } } diff --git a/plans/vulkan-hpp-migration-plan.md b/plans/vulkan-hpp-migration-plan.md new file mode 100644 index 0000000..4c9e98b --- /dev/null +++ b/plans/vulkan-hpp-migration-plan.md @@ -0,0 +1,317 @@ +# Vulkan C API 到 vulkan.hpp 迁移计划 + +## 1. 概述 + +本文档分析了 mirai 项目中 Vulkan C API 的使用情况,并提供迁移到 vulkan.hpp (Vulkan C++ 绑定) 的详细计划。 + +## 2. 需要迁移的文件 + +### 2.1 src/render/ 目录 + +| 文件 | Vulkan 类型使用情况 | 迁移优先级 | +|------|-------------------|-----------| +| [`vulkan_types.hpp`](../src/render/vulkan_types.hpp) | VkResult, VkSurfaceCapabilitiesKHR, VkSurfaceFormatKHR, VkPresentModeKHR, VkExtent2D, VkPhysicalDevice, VkPhysicalDeviceProperties, VkPhysicalDeviceFeatures, VkPhysicalDeviceVulkan11/12/13Features, VkPhysicalDeviceMemoryProperties, VkFormat, VkColorSpaceKHR | **高** - 核心类型定义 | +| [`vulkan_instance.hpp`](../src/render/vulkan_instance.hpp) | VkInstance, VkDebugUtilsMessengerEXT, VkExtensionProperties, VkLayerProperties, VkSurfaceKHR | **高** - 实例管理 | +| [`vulkan_device.hpp`](../src/render/vulkan_device.hpp) | VkDevice, VkPhysicalDevice, VkQueue, VkMemoryPropertyFlags, VkFormat, VkImageTiling, VkFormatFeatureFlags | **高** - 设备管理 | +| [`swapchain.hpp`](../src/render/swapchain.hpp) | VkSwapchainKHR, VkImage, VkImageView, VkSurfaceFormatKHR, VkExtent2D, VkPresentModeKHR, VkSemaphore, VkFence | **高** - 交换链 | +| [`command_buffer.hpp`](../src/render/command_buffer.hpp) | VkCommandPool, VkCommandBuffer, VkCommandBufferLevel, VkCommandBufferUsageFlags, VkDependencyInfo, VkPipeline, VkBuffer, VkIndexType, VkDescriptorSet, VkPipelineLayout, VkRect2D, VkExtent2D | **中** - 命令缓冲 | +| [`pipeline.hpp`](../src/render/pipeline.hpp) | VkPipelineLayout, VkPipeline, VkShaderModule, VkFormat, VkVertexInputRate, VkPrimitiveTopology, VkPolygonMode, VkCullModeFlags, VkFrontFace, VkSampleCountFlagBits, VkCompareOp, VkStencilOpState, VkBlendFactor, VkBlendOp, VkColorComponentFlags, VkDynamicState, VkDescriptorSetLayout, VkPushConstantRange | **中** - 管线 | +| [`frame_sync.hpp`](../src/render/frame_sync.hpp) | VkSemaphore, VkFence | **低** | +| [`render_pass.hpp`](../src/render/render_pass.hpp) | VkRenderPass, VkFramebuffer | **低** (可能已使用 Dynamic Rendering) | +| [`batch.hpp`](../src/render/batch.hpp) | 可能使用 Vulkan 类型 | **低** | +| [`renderer.hpp`](../src/render/renderer.hpp) | 组合使用其他模块 | **低** | + +### 2.2 src/resource/ 目录 + +| 文件 | Vulkan 类型使用情况 | 迁移优先级 | +|------|-------------------|-----------| +| [`resource_types.hpp`](../src/resource/resource_types.hpp) | 可能定义 Vulkan 相关枚举映射 | **中** | +| [`allocator.hpp`](../src/resource/allocator.hpp) | VmaAllocator, VkBuffer, VkImage, VmaAllocation | **高** - VMA 集成 | +| [`buffer.hpp`](../src/resource/buffer.hpp) | VkBuffer, VkDeviceAddress, VkCommandBuffer, VkDescriptorBufferInfo, VkDeviceSize | **中** | +| [`texture.hpp`](../src/resource/texture.hpp) | VkImage, VkImageSubresourceRange, VkCommandBuffer | **中** | +| [`texture_view.hpp`](../src/resource/texture_view.hpp) | VkImageView | **中** | +| [`sampler.hpp`](../src/resource/sampler.hpp) | VkSampler | **低** | +| [`descriptor_pool.hpp`](../src/resource/descriptor_pool.hpp) | VkDescriptorPool, VkDescriptorSet, VkDescriptorSetLayout, VkDescriptorBufferInfo, VkDescriptorImageInfo, VkBufferView, VkShaderStageFlags, VkSampler, VkImageLayout | **中** | + +### 2.3 src/shader/ 目录 + +| 文件 | Vulkan 类型使用情况 | 迁移优先级 | +|------|-------------------|-----------| +| [`shader_module.hpp`](../src/shader/shader_module.hpp) | VkShaderModule, VkDevice | **中** | +| [`shader_types.hpp`](../src/shader/shader_types.hpp) | 可能包含 Vulkan 类型映射 | **中** | +| [`shader_reflection.hpp`](../src/shader/shader_reflection.hpp) | 可能使用 Vulkan 描述符类型 | **低** | +| [`shader_program.hpp`](../src/shader/shader_program.hpp) | 组合 shader_module | **低** | + +## 3. Vulkan 类型使用统计 + +### 3.1 核心句柄类型 +- `VkInstance` - 实例 +- `VkPhysicalDevice` - 物理设备 +- `VkDevice` - 逻辑设备 +- `VkQueue` - 队列 +- `VkSurfaceKHR` - 表面 +- `VkSwapchainKHR` - 交换链 +- `VkCommandPool` - 命令池 +- `VkCommandBuffer` - 命令缓冲 +- `VkBuffer` - 缓冲 +- `VkImage` - 图像 +- `VkImageView` - 图像视图 +- `VkSampler` - 采样器 +- `VkPipeline` - 管线 +- `VkPipelineLayout` - 管线布局 +- `VkDescriptorPool` - 描述符池 +- `VkDescriptorSet` - 描述符集 +- `VkDescriptorSetLayout` - 描述符集布局 +- `VkShaderModule` - 着色器模块 +- `VkSemaphore` - 信号量 +- `VkFence` - 栅栏 +- `VkDebugUtilsMessengerEXT` - 调试信使 + +### 3.2 结构体类型 +- `VkPhysicalDeviceProperties` +- `VkPhysicalDeviceFeatures` +- `VkPhysicalDeviceVulkan11Features` +- `VkPhysicalDeviceVulkan12Features` +- `VkPhysicalDeviceVulkan13Features` +- `VkPhysicalDeviceMemoryProperties` +- `VkSurfaceCapabilitiesKHR` +- `VkSurfaceFormatKHR` +- `VkExtent2D` +- `VkRect2D` +- `VkDescriptorBufferInfo` +- `VkDescriptorImageInfo` +- `VkImageSubresourceRange` +- `VkDependencyInfo` +- `VkPushConstantRange` +- `VkStencilOpState` +- `VkPipelineColorBlendAttachmentState` +- `VkExtensionProperties` +- `VkLayerProperties` + +### 3.3 枚举类型 +- `VkResult` +- `VkFormat` +- `VkColorSpaceKHR` +- `VkPresentModeKHR` +- `VkImageLayout` +- `VkPrimitiveTopology` +- `VkPolygonMode` +- `VkCullModeFlags` +- `VkFrontFace` +- `VkCompareOp` +- `VkBlendFactor` +- `VkBlendOp` +- `VkDynamicState` +- `VkShaderStageFlags` +- `VkVertexInputRate` +- `VkSampleCountFlagBits` +- `VkIndexType` +- `VkCommandBufferLevel` +- `VkImageTiling` +- `VkMemoryPropertyFlags` +- `VkFormatFeatureFlags` +- `VkColorComponentFlags` + +## 4. 迁移策略 + +### 4.1 是否需要包装层 + +**建议:不需要创建单独的 vulkan_wrapper.hpp** + +理由: +1. vulkan.hpp 本身已经是 C API 的 C++ 包装 +2. 项目已有良好的抽象层(vulkan_instance, vulkan_device 等类) +3. 直接在现有类中使用 vulkan.hpp 类型即可 + +### 4.2 迁移方式 + +**推荐:渐进式迁移** + +```cpp +// 迁移前 +#include +VkDevice device = VK_NULL_HANDLE; + +// 迁移后 +#include +vk::Device device; // 或 vk::UniqueDevice 用于 RAII +``` + +### 4.3 关键转换对照表 + +| C API | vulkan.hpp | 备注 | +|-------|-----------|------| +| `VkInstance` | `vk::Instance` | | +| `VkDevice` | `vk::Device` / `vk::UniqueDevice` | UniqueDevice 自动管理生命周期 | +| `VkPhysicalDevice` | `vk::PhysicalDevice` | | +| `VkQueue` | `vk::Queue` | | +| `VkCommandBuffer` | `vk::CommandBuffer` | | +| `VkBuffer` | `vk::Buffer` / `vk::UniqueBuffer` | | +| `VkImage` | `vk::Image` / `vk::UniqueImage` | | +| `VK_NULL_HANDLE` | `nullptr` 或默认构造 | | +| `VK_SUCCESS` | `vk::Result::eSuccess` | | +| `vkCreateXxx()` | `device.createXxx()` | 成员函数 | +| `vkDestroyXxx()` | `device.destroyXxx()` | 或使用 UniqueXxx 自动销毁 | +| `VkResult` | `vk::Result` 或异常 | | + +### 4.4 错误处理策略 + +vulkan.hpp 支持两种错误处理方式: + +1. **异常模式**(默认): +```cpp +try { + auto device = instance.createDevice(createInfo); +} catch (vk::SystemError& e) { + // 处理错误 +} +``` + +2. **返回值模式**: +```cpp +#define VULKAN_HPP_NO_EXCEPTIONS +auto [result, device] = instance.createDevice(createInfo); +if (result != vk::Result::eSuccess) { + // 处理错误 +} +``` + +**建议:使用返回值模式**,与项目现有的 `result` 错误处理风格一致。 + +## 5. 迁移顺序 + +### 阶段 1:基础设施(高优先级) +1. [`vulkan_types.hpp`](../src/render/vulkan_types.hpp) - 更新类型定义 +2. [`vulkan_instance.hpp`](../src/render/vulkan_instance.hpp) / `.cpp` +3. [`vulkan_device.hpp`](../src/render/vulkan_device.hpp) / `.cpp` +4. [`allocator.hpp`](../src/resource/allocator.hpp) / `.cpp` - VMA 集成 + +### 阶段 2:资源管理(中优先级) +5. [`swapchain.hpp`](../src/render/swapchain.hpp) / `.cpp` +6. [`buffer.hpp`](../src/resource/buffer.hpp) / `.cpp` +7. [`texture.hpp`](../src/resource/texture.hpp) / `.cpp` +8. [`texture_view.hpp`](../src/resource/texture_view.hpp) / `.cpp` +9. [`descriptor_pool.hpp`](../src/resource/descriptor_pool.hpp) / `.cpp` + +### 阶段 3:渲染管线(中优先级) +10. [`command_buffer.hpp`](../src/render/command_buffer.hpp) / `.cpp` +11. [`pipeline.hpp`](../src/render/pipeline.hpp) / `.cpp` +12. [`shader_module.hpp`](../src/shader/shader_module.hpp) / `.cpp` + +### 阶段 4:其他模块(低优先级) +13. [`frame_sync.hpp`](../src/render/frame_sync.hpp) / `.cpp` +14. [`sampler.hpp`](../src/resource/sampler.hpp) / `.cpp` +15. 其他 shader 相关文件 +16. [`renderer.hpp`](../src/render/renderer.hpp) / `.cpp` + +## 6. 兼容性注意事项 + +### 6.1 VMA (Vulkan Memory Allocator) 集成 + +VMA 使用 C API,需要特殊处理: + +```cpp +// 从 vulkan.hpp 类型获取 C 句柄 +vk::Device device; +VkDevice c_device = static_cast(device); +// 或 +VkDevice c_device = *device; + +// 将 C 句柄转换为 vulkan.hpp 类型 +VkBuffer c_buffer = ...; +vk::Buffer buffer(c_buffer); +``` + +### 6.2 与现有代码的兼容 + +- vulkan.hpp 类型可以隐式转换为 C 类型 +- C 类型需要显式构造为 vulkan.hpp 类型 +- 建议在迁移期间保持 getter 方法返回 C 类型以保持兼容 + +### 6.3 编译器要求 + +- 需要 C++17 或更高版本(项目已使用 C++20) +- 需要定义 `VULKAN_HPP_DISPATCH_LOADER_DYNAMIC 1` 使用动态加载 + +### 6.4 CMake 配置 + +```cmake +# vcpkg.json 添加 +{ + "dependencies": [ + "vulkan", + "vulkan-hpp" + ] +} + +# 或直接使用 Vulkan SDK 自带的 vulkan.hpp +find_package(Vulkan REQUIRED) +target_link_libraries(${PROJECT_NAME} Vulkan::Vulkan) +``` + +## 7. 代码示例 + +### 7.1 迁移前后对比 + +**迁移前 (vulkan_instance.cpp):** +```cpp +VkInstanceCreateInfo create_info{}; +create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; +create_info.pApplicationInfo = &app_info; +create_info.enabledExtensionCount = static_cast(extensions.size()); +create_info.ppEnabledExtensionNames = extensions.data(); + +VkResult result = vkCreateInstance(&create_info, nullptr, &instance_); +if (result != VK_SUCCESS) { + return error("Failed to create Vulkan instance"); +} +``` + +**迁移后:** +```cpp +vk::InstanceCreateInfo create_info{}; +create_info.setPApplicationInfo(&app_info) + .setEnabledExtensionCount(static_cast(extensions.size())) + .setPpEnabledExtensionNames(extensions.data()); + +auto [result, instance] = vk::createInstance(create_info); +if (result != vk::Result::eSuccess) { + return error("Failed to create Vulkan instance"); +} +instance_ = instance; +``` + +### 7.2 使用 UniqueHandle 简化资源管理 + +```cpp +// 使用 UniqueDevice 自动管理设备生命周期 +vk::UniqueDevice device = physicalDevice.createDeviceUnique(createInfo); + +// 设备会在 unique_ptr 销毁时自动调用 vkDestroyDevice +``` + +## 8. 测试策略 + +1. **单元测试**:每个迁移的模块需要通过现有单元测试 +2. **集成测试**:确保渲染管线正常工作 +3. **性能测试**:验证没有性能回退(vulkan.hpp 是零开销抽象) + +## 9. 风险评估 + +| 风险 | 影响 | 缓解措施 | +|------|------|---------| +| VMA 兼容性问题 | 中 | 在 allocator 层做类型转换 | +| 编译时间增加 | 低 | vulkan.hpp 主要是头文件,可能增加编译时间 | +| 调试困难 | 低 | 使用 Vulkan Validation Layers | +| 团队学习成本 | 低 | vulkan.hpp 语法直观,学习曲线平缓 | + +## 10. 总结 + +迁移到 vulkan.hpp 将带来以下好处: +- 更安全的类型系统 +- 更简洁的代码 +- 更好的 IDE 支持(自动补全) +- 可选的 RAII 资源管理 +- 更现代的 C++ 风格 + +建议采用渐进式迁移策略,从基础设施层开始,逐步扩展到其他模块。 \ No newline at end of file diff --git a/src/core/assert.hpp b/src/core/assert.hpp index adaecdf..43578a8 100644 --- a/src/core/assert.hpp +++ b/src/core/assert.hpp @@ -180,7 +180,7 @@ inline bool handle_verify_failure( * // 设置自定义处理器 * auto old_handler = milai::set_assertion_handler([](const auto& info) { * // 记录到日志 - * log_error(info.format()); + * MILAI_LOG_ERROR(info.format()); * // 返回 false 终止程序 * return false; * }); diff --git a/src/core/object.hpp b/src/core/object.hpp index d8ec269..7d1d142 100644 --- a/src/core/object.hpp +++ b/src/core/object.hpp @@ -296,6 +296,16 @@ public: } return nullptr; } + + #if MILAI_DEBUG + void set_debug_name(std::string name) { + debug_name_ = std::move(name); + } + + [[nodiscard]] const std::string& get_debug_name() const noexcept { + return debug_name_; + } + #endif // ============================================================================================ // 对象标识 @@ -390,6 +400,10 @@ protected: private: /// 对象唯一标识符 object_id id_; + +#if MILAI_DEBUG + std::string debug_name_; +#endif /// 全局对象 ID 计数器 static std::atomic next_id_; diff --git a/src/debug/gpu_profiler.cpp b/src/debug/gpu_profiler.cpp index 10d1fe4..d2f1a8a 100644 --- a/src/debug/gpu_profiler.cpp +++ b/src/debug/gpu_profiler.cpp @@ -32,7 +32,7 @@ bool gpu_profiler::initialize(const init_info& info) { return true; } - if (info.device == VK_NULL_HANDLE || info.physical_device == VK_NULL_HANDLE) { + if (!info.device || !info.physical_device) { return false; } @@ -41,8 +41,7 @@ bool gpu_profiler::initialize(const init_info& info) { config_ = info.config; // 获取时间戳周期 - VkPhysicalDeviceProperties properties{}; - vkGetPhysicalDeviceProperties(physical_device_, &properties); + vk::PhysicalDeviceProperties properties = physical_device_.getProperties(); timestamp_period_ = static_cast(properties.limits.timestampPeriod); // 检查是否支持时间戳 @@ -66,8 +65,8 @@ void gpu_profiler::shutdown() { destroy_query_pools(); - device_ = VK_NULL_HANDLE; - physical_device_ = VK_NULL_HANDLE; + device_ = nullptr; + physical_device_ = nullptr; initialized_ = false; // 清空数据 @@ -81,63 +80,63 @@ void gpu_profiler::shutdown() { bool gpu_profiler::create_query_pools() { // 创建时间戳查询池 - VkQueryPoolCreateInfo timestamp_pool_info{}; - timestamp_pool_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO; - timestamp_pool_info.queryType = VK_QUERY_TYPE_TIMESTAMP; + vk::QueryPoolCreateInfo timestamp_pool_info{}; + timestamp_pool_info.queryType = vk::QueryType::eTimestamp; timestamp_pool_info.queryCount = config_.timestamp_query_count; - VkResult result = vkCreateQueryPool(device_, ×tamp_pool_info, nullptr, ×tamp_query_pool_); - if (result != VK_SUCCESS) { + auto [result, query_pool] = device_.createQueryPool(timestamp_pool_info); + if (result != vk::Result::eSuccess) { return false; } + timestamp_query_pool_ = query_pool; // 创建管线统计查询池 if (config_.enable_pipeline_statistics) { - VkQueryPoolCreateInfo stats_pool_info{}; - stats_pool_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO; - stats_pool_info.queryType = VK_QUERY_TYPE_PIPELINE_STATISTICS; + vk::QueryPoolCreateInfo stats_pool_info{}; + stats_pool_info.queryType = vk::QueryType::ePipelineStatistics; stats_pool_info.queryCount = config_.pipeline_statistics_query_count; - stats_pool_info.pipelineStatistics = - VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT | - VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT | - VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT | - VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_INVOCATIONS_BIT | - VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_PRIMITIVES_BIT | - VK_QUERY_PIPELINE_STATISTIC_CLIPPING_INVOCATIONS_BIT | - VK_QUERY_PIPELINE_STATISTIC_CLIPPING_PRIMITIVES_BIT | - VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT | - VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_CONTROL_SHADER_PATCHES_BIT | - VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_EVALUATION_SHADER_INVOCATIONS_BIT | - VK_QUERY_PIPELINE_STATISTIC_COMPUTE_SHADER_INVOCATIONS_BIT; + stats_pool_info.pipelineStatistics = + vk::QueryPipelineStatisticFlagBits::eInputAssemblyVertices | + vk::QueryPipelineStatisticFlagBits::eInputAssemblyPrimitives | + vk::QueryPipelineStatisticFlagBits::eVertexShaderInvocations | + vk::QueryPipelineStatisticFlagBits::eGeometryShaderInvocations | + vk::QueryPipelineStatisticFlagBits::eGeometryShaderPrimitives | + vk::QueryPipelineStatisticFlagBits::eClippingInvocations | + vk::QueryPipelineStatisticFlagBits::eClippingPrimitives | + vk::QueryPipelineStatisticFlagBits::eFragmentShaderInvocations | + vk::QueryPipelineStatisticFlagBits::eTessellationControlShaderPatches | + vk::QueryPipelineStatisticFlagBits::eTessellationEvaluationShaderInvocations | + vk::QueryPipelineStatisticFlagBits::eComputeShaderInvocations; - result = vkCreateQueryPool(device_, &stats_pool_info, nullptr, &pipeline_stats_query_pool_); - if (result != VK_SUCCESS) { - vkDestroyQueryPool(device_, timestamp_query_pool_, nullptr); - timestamp_query_pool_ = VK_NULL_HANDLE; + auto [stats_result, stats_pool] = device_.createQueryPool(stats_pool_info); + if (stats_result != vk::Result::eSuccess) { + device_.destroyQueryPool(timestamp_query_pool_); + timestamp_query_pool_ = nullptr; return false; } + pipeline_stats_query_pool_ = stats_pool; } return true; } void gpu_profiler::destroy_query_pools() { - if (device_ == VK_NULL_HANDLE) { + if (!device_) { return; } - if (timestamp_query_pool_ != VK_NULL_HANDLE) { - vkDestroyQueryPool(device_, timestamp_query_pool_, nullptr); - timestamp_query_pool_ = VK_NULL_HANDLE; + if (timestamp_query_pool_) { + device_.destroyQueryPool(timestamp_query_pool_); + timestamp_query_pool_ = nullptr; } - if (pipeline_stats_query_pool_ != VK_NULL_HANDLE) { - vkDestroyQueryPool(device_, pipeline_stats_query_pool_, nullptr); - pipeline_stats_query_pool_ = VK_NULL_HANDLE; + if (pipeline_stats_query_pool_) { + device_.destroyQueryPool(pipeline_stats_query_pool_); + pipeline_stats_query_pool_ = nullptr; } } -void gpu_profiler::begin_frame(VkCommandBuffer cmd_buffer) { +void gpu_profiler::begin_frame(vk::CommandBuffer cmd_buffer) { if (!is_enabled()) { return; } @@ -150,22 +149,22 @@ void gpu_profiler::begin_frame(VkCommandBuffer cmd_buffer) { current_frame_queries_.clear(); // 重置查询池 - vkCmdResetQueryPool(cmd_buffer, timestamp_query_pool_, 0, config_.timestamp_query_count); + cmd_buffer.resetQueryPool(timestamp_query_pool_, 0, config_.timestamp_query_count); - if (config_.enable_pipeline_statistics && pipeline_stats_query_pool_ != VK_NULL_HANDLE) { - vkCmdResetQueryPool(cmd_buffer, pipeline_stats_query_pool_, 0, config_.pipeline_statistics_query_count); + if (config_.enable_pipeline_statistics && pipeline_stats_query_pool_) { + cmd_buffer.resetQueryPool(pipeline_stats_query_pool_, 0, config_.pipeline_statistics_query_count); pipeline_stats_query_id_ = 0; } // 写入帧开始时间戳 frame_start_query_ = allocate_timestamp_query(); - vkCmdWriteTimestamp(cmd_buffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, + cmd_buffer.writeTimestamp(vk::PipelineStageFlagBits::eTopOfPipe, timestamp_query_pool_, frame_start_query_); in_frame_ = true; } -void gpu_profiler::end_frame(VkCommandBuffer cmd_buffer) { +void gpu_profiler::end_frame(vk::CommandBuffer cmd_buffer) { if (!is_enabled() || !in_frame_) { return; } @@ -179,7 +178,7 @@ void gpu_profiler::end_frame(VkCommandBuffer cmd_buffer) { // 写入帧结束时间戳 frame_end_query_ = allocate_timestamp_query(); - vkCmdWriteTimestamp(cmd_buffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, + cmd_buffer.writeTimestamp(vk::PipelineStageFlagBits::eBottomOfPipe, timestamp_query_pool_, frame_end_query_); in_frame_ = false; @@ -211,16 +210,16 @@ void gpu_profiler::collect_results() { } // 读取管线统计 - if (config_.enable_pipeline_statistics && pipeline_stats_query_pool_ != VK_NULL_HANDLE && pipeline_stats_active_) { + if (config_.enable_pipeline_statistics && pipeline_stats_query_pool_ && pipeline_stats_active_) { u64 stats_data[11] = {0}; - VkResult result = vkGetQueryPoolResults( - device_, pipeline_stats_query_pool_, + auto result = device_.getQueryPoolResults( + pipeline_stats_query_pool_, pipeline_stats_query_id_, 1, sizeof(stats_data), stats_data, sizeof(u64), - VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT + vk::QueryResultFlagBits::e64 | vk::QueryResultFlagBits::eWait ); - if (result == VK_SUCCESS) { + if (result == vk::Result::eSuccess) { pipeline_stats_.input_assembly_vertices = stats_data[0]; pipeline_stats_.input_assembly_primitives = stats_data[1]; pipeline_stats_.vertex_shader_invocations = stats_data[2]; @@ -238,7 +237,7 @@ void gpu_profiler::collect_results() { } } -void gpu_profiler::begin_gpu_scope(std::string_view name, VkCommandBuffer cmd_buffer) { +void gpu_profiler::begin_gpu_scope(std::string_view name, vk::CommandBuffer cmd_buffer) { if (!is_enabled() || !in_frame_) { return; } @@ -247,7 +246,7 @@ void gpu_profiler::begin_gpu_scope(std::string_view name, VkCommandBuffer cmd_bu // 分配查询 ID 并写入开始时间戳 u32 start_query = allocate_timestamp_query(); - vkCmdWriteTimestamp(cmd_buffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, + cmd_buffer.writeTimestamp(vk::PipelineStageFlagBits::eTopOfPipe, timestamp_query_pool_, start_query); // 压入作用域栈 @@ -257,7 +256,7 @@ void gpu_profiler::begin_gpu_scope(std::string_view name, VkCommandBuffer cmd_bu scope_stack_.push_back(std::move(entry)); } -void gpu_profiler::end_gpu_scope(VkCommandBuffer cmd_buffer) { +void gpu_profiler::end_gpu_scope(vk::CommandBuffer cmd_buffer) { if (!is_enabled() || !in_frame_ || scope_stack_.empty()) { return; } @@ -270,7 +269,7 @@ void gpu_profiler::end_gpu_scope(VkCommandBuffer cmd_buffer) { // 写入结束时间戳 u32 end_query = allocate_timestamp_query(); - vkCmdWriteTimestamp(cmd_buffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, + cmd_buffer.writeTimestamp(vk::PipelineStageFlagBits::eBottomOfPipe, timestamp_query_pool_, end_query); // 记录查询信息 @@ -283,27 +282,27 @@ void gpu_profiler::end_gpu_scope(VkCommandBuffer cmd_buffer) { current_frame_queries_.push_back(std::move(query)); } -void gpu_profiler::begin_pipeline_statistics(VkCommandBuffer cmd_buffer) { - if (!is_enabled() || !config_.enable_pipeline_statistics || - pipeline_stats_query_pool_ == VK_NULL_HANDLE) { +void gpu_profiler::begin_pipeline_statistics(vk::CommandBuffer cmd_buffer) { + if (!is_enabled() || !config_.enable_pipeline_statistics || + !pipeline_stats_query_pool_) { return; } std::unique_lock lock(mutex_); - vkCmdBeginQuery(cmd_buffer, pipeline_stats_query_pool_, pipeline_stats_query_id_, 0); + cmd_buffer.beginQuery(pipeline_stats_query_pool_, pipeline_stats_query_id_, vk::QueryControlFlags{}); pipeline_stats_active_ = true; } -void gpu_profiler::end_pipeline_statistics(VkCommandBuffer cmd_buffer) { - if (!is_enabled() || !pipeline_stats_active_ || - pipeline_stats_query_pool_ == VK_NULL_HANDLE) { +void gpu_profiler::end_pipeline_statistics(vk::CommandBuffer cmd_buffer) { + if (!is_enabled() || !pipeline_stats_active_ || + !pipeline_stats_query_pool_) { return; } std::unique_lock lock(mutex_); - vkCmdEndQuery(cmd_buffer, pipeline_stats_query_pool_, pipeline_stats_query_id_); + cmd_buffer.endQuery(pipeline_stats_query_pool_, pipeline_stats_query_id_); } f64 gpu_profiler::get_gpu_time(std::string_view name) const { @@ -398,26 +397,26 @@ u64 gpu_profiler::read_timestamp_duration(u32 start_query_id, u32 end_query_id) u64 timestamps[2] = {0, 0}; // 读取开始时间戳 - VkResult result = vkGetQueryPoolResults( - device_, timestamp_query_pool_, + auto result = device_.getQueryPoolResults( + timestamp_query_pool_, start_query_id, 1, sizeof(u64), ×tamps[0], sizeof(u64), - VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT + vk::QueryResultFlagBits::e64 | vk::QueryResultFlagBits::eWait ); - if (result != VK_SUCCESS) { + if (result != vk::Result::eSuccess) { return 0; } // 读取结束时间戳 - result = vkGetQueryPoolResults( - device_, timestamp_query_pool_, + result = device_.getQueryPoolResults( + timestamp_query_pool_, end_query_id, 1, sizeof(u64), ×tamps[1], sizeof(u64), - VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT + vk::QueryResultFlagBits::e64 | vk::QueryResultFlagBits::eWait ); - if (result != VK_SUCCESS) { + if (result != vk::Result::eSuccess) { return 0; } diff --git a/src/debug/gpu_profiler.hpp b/src/debug/gpu_profiler.hpp index 46d627d..a2717d3 100644 --- a/src/debug/gpu_profiler.hpp +++ b/src/debug/gpu_profiler.hpp @@ -14,10 +14,9 @@ #pragma once #include "debug_types.hpp" +#include "vulkan_types.hpp" #include "types.hpp" -#include - #include #include #include @@ -97,10 +96,10 @@ public: */ struct init_info { /// Vulkan 逻辑设备 - VkDevice device{VK_NULL_HANDLE}; + vk::Device device; /// Vulkan 物理设备 - VkPhysicalDevice physical_device{VK_NULL_HANDLE}; + vk::PhysicalDevice physical_device; /// 查询池配置 gpu_query_pool_config config{}; @@ -167,13 +166,13 @@ public: * @brief 开始新帧 * @param cmd_buffer 命令缓冲区 */ - void begin_frame(VkCommandBuffer cmd_buffer); + void begin_frame(vk::CommandBuffer cmd_buffer); /** * @brief 结束当前帧 * @param cmd_buffer 命令缓冲区 */ - void end_frame(VkCommandBuffer cmd_buffer); + void end_frame(vk::CommandBuffer cmd_buffer); /** * @brief 收集上一帧的结果 @@ -191,13 +190,13 @@ public: * @param name 作用域名称 * @param cmd_buffer 命令缓冲区 */ - void begin_gpu_scope(std::string_view name, VkCommandBuffer cmd_buffer); + void begin_gpu_scope(std::string_view name, vk::CommandBuffer cmd_buffer); /** * @brief 结束 GPU 作用域计时 * @param cmd_buffer 命令缓冲区 */ - void end_gpu_scope(VkCommandBuffer cmd_buffer); + void end_gpu_scope(vk::CommandBuffer cmd_buffer); // ============================================================================================ // 管线统计 @@ -207,13 +206,13 @@ public: * @brief 开始管线统计查询 * @param cmd_buffer 命令缓冲区 */ - void begin_pipeline_statistics(VkCommandBuffer cmd_buffer); + void begin_pipeline_statistics(vk::CommandBuffer cmd_buffer); /** * @brief 结束管线统计查询 * @param cmd_buffer 命令缓冲区 */ - void end_pipeline_statistics(VkCommandBuffer cmd_buffer); + void end_pipeline_statistics(vk::CommandBuffer cmd_buffer); // ============================================================================================ // 结果查询 @@ -329,19 +328,19 @@ private: std::atomic enabled_{true}; /// Vulkan 设备 - VkDevice device_{VK_NULL_HANDLE}; + vk::Device device_; /// 物理设备 - VkPhysicalDevice physical_device_{VK_NULL_HANDLE}; + vk::PhysicalDevice physical_device_; /// 配置 gpu_query_pool_config config_{}; /// 时间戳查询池 - VkQueryPool timestamp_query_pool_{VK_NULL_HANDLE}; + vk::QueryPool timestamp_query_pool_; /// 管线统计查询池 - VkQueryPool pipeline_stats_query_pool_{VK_NULL_HANDLE}; + vk::QueryPool pipeline_stats_query_pool_; /// 时间戳周期(纳秒) f64 timestamp_period_{1.0}; @@ -402,8 +401,8 @@ private: */ #define MILAI_GPU_PROFILE_SCOPE(name, cmd) \ struct _milai_gpu_scope_##__LINE__ { \ - VkCommandBuffer cmd_; \ - _milai_gpu_scope_##__LINE__(const char* n, VkCommandBuffer c) : cmd_(c) { \ + vk::CommandBuffer cmd_; \ + _milai_gpu_scope_##__LINE__(const char* n, vk::CommandBuffer c) : cmd_(c) { \ ::milai::gpu_profiler::instance().begin_gpu_scope(n, c); \ } \ ~_milai_gpu_scope_##__LINE__() { \ diff --git a/src/render/batch.cpp b/src/render/batch.cpp index cba3ffc..36fb04f 100644 --- a/src/render/batch.cpp +++ b/src/render/batch.cpp @@ -210,16 +210,16 @@ batch_renderer::batch_renderer(batch_renderer&& other) noexcept , initialized_(other.initialized_) , batching_(other.batching_) { - other.allocator_ = VK_NULL_HANDLE; - other.vertex_buffer_ = VK_NULL_HANDLE; - other.vertex_allocation_ = VK_NULL_HANDLE; - other.index_buffer_ = VK_NULL_HANDLE; - other.index_allocation_ = VK_NULL_HANDLE; - other.staging_buffer_ = VK_NULL_HANDLE; - other.staging_allocation_ = VK_NULL_HANDLE; + other.allocator_ = nullptr; + other.vertex_buffer_ = nullptr; + other.vertex_allocation_ = nullptr; + other.index_buffer_ = nullptr; + other.index_allocation_ = nullptr; + other.staging_buffer_ = nullptr; + other.staging_allocation_ = nullptr; other.staging_mapped_data_ = nullptr; - other.current_cmd_buffer_ = VK_NULL_HANDLE; - other.current_descriptor_set_ = VK_NULL_HANDLE; + other.current_cmd_buffer_ = nullptr; + other.current_descriptor_set_ = nullptr; other.initialized_ = false; other.batching_ = false; } @@ -251,49 +251,49 @@ batch_renderer& batch_renderer::operator=(batch_renderer&& other) noexcept { initialized_ = other.initialized_; batching_ = other.batching_; - other.allocator_ = VK_NULL_HANDLE; - other.vertex_buffer_ = VK_NULL_HANDLE; - other.vertex_allocation_ = VK_NULL_HANDLE; - other.index_buffer_ = VK_NULL_HANDLE; - other.index_allocation_ = VK_NULL_HANDLE; - other.staging_buffer_ = VK_NULL_HANDLE; - other.staging_allocation_ = VK_NULL_HANDLE; + other.allocator_ = nullptr; + other.vertex_buffer_ = nullptr; + other.vertex_allocation_ = nullptr; + other.index_buffer_ = nullptr; + other.index_allocation_ = nullptr; + other.staging_buffer_ = nullptr; + other.staging_allocation_ = nullptr; other.staging_mapped_data_ = nullptr; - other.current_cmd_buffer_ = VK_NULL_HANDLE; - other.current_descriptor_set_ = VK_NULL_HANDLE; + other.current_cmd_buffer_ = nullptr; + other.current_descriptor_set_ = nullptr; other.initialized_ = false; other.batching_ = false; } return *this; } -bool batch_renderer::initialize(VkFormat color_format, VkFormat depth_format) { +bool batch_renderer::initialize(vk::Format color_format, vk::Format depth_format) { if (initialized_) { - LOG_WARN("Batch renderer already initialized"); + MILAI_LOG_WARN("Batch renderer already initialized"); return true; } - if (!device_ || !device_->is_valid() || allocator_ == VK_NULL_HANDLE) { - LOG_ERROR("Invalid device or allocator"); + if (!device_ || !device_->is_valid() || allocator_ == nullptr) { + MILAI_LOG_ERROR("Invalid device or allocator"); return false; } // 创建缓冲资源 if (!create_buffers()) { - LOG_ERROR("Failed to create batch renderer buffers"); + MILAI_LOG_ERROR("Failed to create batch renderer buffers"); return false; } // 创建管线布局 if (!create_pipeline_layout()) { - LOG_ERROR("Failed to create batch renderer pipeline layout"); + MILAI_LOG_ERROR("Failed to create batch renderer pipeline layout"); destroy_resources(); return false; } // 创建管线 if (!create_pipeline(color_format, depth_format)) { - LOG_ERROR("Failed to create batch renderer pipeline"); + MILAI_LOG_ERROR("Failed to create batch renderer pipeline"); destroy_resources(); return false; } @@ -303,18 +303,18 @@ bool batch_renderer::initialize(VkFormat color_format, VkFormat depth_format) { static_cast(config_.viewport_height)); initialized_ = true; - LOG_DEBUG("Batch renderer initialized with max {} quads", max_quads_); + MILAI_LOG_DEBUG("Batch renderer initialized with max {} quads", max_quads_); return true; } -void batch_renderer::begin(VkCommandBuffer cmd_buffer) { +void batch_renderer::begin(vk::CommandBuffer cmd_buffer) { if (!initialized_) { - LOG_ERROR("Batch renderer not initialized"); + MILAI_LOG_ERROR("Batch renderer not initialized"); return; } if (batching_) { - LOG_WARN("Batch renderer already in batching mode"); + MILAI_LOG_WARN("Batch renderer already in batching mode"); return; } @@ -326,40 +326,40 @@ void batch_renderer::begin(VkCommandBuffer cmd_buffer) { current_quad_count_ = 0; // 绑定管线 - vkCmdBindPipeline(cmd_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, - pipeline_->get_vulkan_pipeline()); + cmd_buffer.bindPipeline(vk::PipelineBindPoint::eGraphics, + pipeline_->get_vulkan_pipeline()); // 绑定顶点缓冲 - VkBuffer vertex_buffers[] = {vertex_buffer_}; - VkDeviceSize offsets[] = {0}; - vkCmdBindVertexBuffers(cmd_buffer, 0, 1, vertex_buffers, offsets); + vk::Buffer vertex_buffers[] = {vertex_buffer_}; + vk::DeviceSize offsets[] = {0}; + cmd_buffer.bindVertexBuffers(0, 1, vertex_buffers, offsets); // 绑定索引缓冲 - vkCmdBindIndexBuffer(cmd_buffer, index_buffer_, 0, VK_INDEX_TYPE_UINT32); + cmd_buffer.bindIndexBuffer(index_buffer_, 0, vk::IndexType::eUint32); // 推送投影视图矩阵 - vkCmdPushConstants(cmd_buffer, pipeline_layout_->get_vulkan_layout(), - VK_SHADER_STAGE_VERTEX_BIT, 0, - sizeof(batch_push_constants), &push_constants_); + cmd_buffer.pushConstants(pipeline_layout_->get_vulkan_layout(), + vk::ShaderStageFlagBits::eVertex, 0, + sizeof(batch_push_constants), &push_constants_); // 绑定描述符集(如果有) - if (current_descriptor_set_ != VK_NULL_HANDLE) { - vkCmdBindDescriptorSets(cmd_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, - pipeline_layout_->get_vulkan_layout(), - 0, 1, ¤t_descriptor_set_, 0, nullptr); + if (current_descriptor_set_) { + cmd_buffer.bindDescriptorSets(vk::PipelineBindPoint::eGraphics, + pipeline_layout_->get_vulkan_layout(), + 0, 1, ¤t_descriptor_set_, 0, nullptr); } } void batch_renderer::end() { if (!batching_) { - LOG_WARN("Batch renderer not in batching mode"); + MILAI_LOG_WARN("Batch renderer not in batching mode"); return; } // 刷新剩余的绘制命令 flush(); - current_cmd_buffer_ = VK_NULL_HANDLE; + current_cmd_buffer_ = nullptr; batching_ = false; } @@ -397,7 +397,7 @@ void batch_renderer::draw_rotated_textured_quad(const glm::vec2& center, const g void batch_renderer::draw_quad(const batch_quad& quad) { if (!batching_) { - LOG_ERROR("Cannot draw quad: not in batching mode"); + MILAI_LOG_ERROR("Cannot draw quad: not in batching mode"); return; } @@ -422,7 +422,7 @@ void batch_renderer::flush() { // 绘制 u32 index_count = current_quad_count_ * 6; - vkCmdDrawIndexed(current_cmd_buffer_, index_count, 1, 0, 0, 0); + current_cmd_buffer_.drawIndexed(index_count, 1, 0, 0, 0); // 更新统计 ++statistics_.draw_calls; @@ -460,45 +460,45 @@ void batch_renderer::set_viewport_orthographic(f32 width, f32 height) { push_constants_.projection_view = glm::ortho(0.0f, width, height, 0.0f, -1.0f, 1.0f); } -void batch_renderer::bind_texture(u32 slot, VkImageView image_view, VkSampler sampler) { +void batch_renderer::bind_texture(u32 slot, vk::ImageView image_view, vk::Sampler sampler) { // 纹理绑定通过描述符集实现 // 这里只记录绑定请求,实际更新需要通过描述符池 if (slot >= max_texture_slots_) { - LOG_ERROR("Texture slot {} exceeds max slots {}", slot, max_texture_slots_); + MILAI_LOG_ERROR("Texture slot {} exceeds max slots {}", slot, max_texture_slots_); return; } // TODO: 实现纹理绑定更新 - LOG_DEBUG("Texture bound to slot {}", slot); + MILAI_LOG_DEBUG("Texture bound to slot {}", slot); } -void batch_renderer::set_descriptor_set(VkDescriptorSet descriptor_set) { +void batch_renderer::set_descriptor_set(vk::DescriptorSet descriptor_set) { current_descriptor_set_ = descriptor_set; // 如果正在批处理中,需要刷新并重新绑定 - if (batching_ && current_cmd_buffer_ != VK_NULL_HANDLE) { + if (batching_ && current_cmd_buffer_) { flush(); - if (descriptor_set != VK_NULL_HANDLE) { - vkCmdBindDescriptorSets(current_cmd_buffer_, VK_PIPELINE_BIND_POINT_GRAPHICS, - pipeline_layout_->get_vulkan_layout(), - 0, 1, &descriptor_set, 0, nullptr); + if (descriptor_set) { + current_cmd_buffer_.bindDescriptorSets(vk::PipelineBindPoint::eGraphics, + pipeline_layout_->get_vulkan_layout(), + 0, 1, &descriptor_set, 0, nullptr); } } } void batch_renderer::on_created() { - LOG_DEBUG("Batch renderer created"); + MILAI_LOG_DEBUG("Batch renderer created"); } void batch_renderer::on_destroying() { - LOG_DEBUG("Batch renderer destroying"); + MILAI_LOG_DEBUG("Batch renderer destroying"); } bool batch_renderer::create_pipeline_layout() { // 推送常量范围 - VkPushConstantRange push_constant_range{}; - push_constant_range.stageFlags = VK_SHADER_STAGE_VERTEX_BIT; + vk::PushConstantRange push_constant_range{}; + push_constant_range.stageFlags = vk::ShaderStageFlagBits::eVertex; push_constant_range.offset = 0; push_constant_range.size = sizeof(batch_push_constants); @@ -512,7 +512,7 @@ bool batch_renderer::create_pipeline_layout() { return pipeline_layout_->is_valid(); } -bool batch_renderer::create_pipeline(VkFormat color_format, VkFormat depth_format) { +bool batch_renderer::create_pipeline(vk::Format color_format, vk::Format depth_format) { // 注意:这里需要实际的着色器模块 // 由于着色器系统已经存在,实际使用时需要加载着色器 @@ -530,30 +530,30 @@ bool batch_renderer::create_pipeline(VkFormat color_format, VkFormat depth_forma } // 设置拓扑 - builder.set_topology(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST); + builder.set_topology(vk::PrimitiveTopology::eTriangleList); // 设置光栅化 - builder.set_polygon_mode(VK_POLYGON_MODE_FILL); - builder.set_cull_mode(VK_CULL_MODE_NONE); // 2D 渲染不需要剔除 - builder.set_front_face(VK_FRONT_FACE_COUNTER_CLOCKWISE); + builder.set_polygon_mode(vk::PolygonMode::eFill); + builder.set_cull_mode(vk::CullModeFlagBits::eNone); // 2D 渲染不需要剔除 + builder.set_front_face(vk::FrontFace::eCounterClockwise); // 启用混合 builder.enable_blending(true); - builder.set_blend_factors(VK_BLEND_FACTOR_SRC_ALPHA, - VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, - VK_BLEND_FACTOR_ONE, - VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA); + builder.set_blend_factors(vk::BlendFactor::eSrcAlpha, + vk::BlendFactor::eOneMinusSrcAlpha, + vk::BlendFactor::eOne, + vk::BlendFactor::eOneMinusSrcAlpha); // 设置深度测试(如果有深度格式) - if (depth_format != VK_FORMAT_UNDEFINED) { - builder.enable_depth_test(true, VK_COMPARE_OP_LESS_OR_EQUAL); + if (depth_format != vk::Format::eUndefined) { + builder.enable_depth_test(true, vk::CompareOp::eLessOrEqual); builder.enable_depth_write(true); builder.set_depth_format(depth_format); } // 设置动态状态 - builder.add_dynamic_state(VK_DYNAMIC_STATE_VIEWPORT); - builder.add_dynamic_state(VK_DYNAMIC_STATE_SCISSOR); + builder.add_dynamic_state(vk::DynamicState::eViewport); + builder.add_dynamic_state(vk::DynamicState::eScissor); // 设置颜色格式(Dynamic Rendering) builder.set_color_format(color_format); @@ -571,64 +571,70 @@ bool batch_renderer::create_pipeline(VkFormat color_format, VkFormat depth_forma // pipeline_ = builder.build(); // return pipeline_ != nullptr && pipeline_->is_valid(); - LOG_WARN("Batch renderer pipeline creation requires shaders - skipping for now"); + MILAI_LOG_WARN("Batch renderer pipeline creation requires shaders - skipping for now"); return true; // 暂时返回 true,实际使用时需要着色器 } bool batch_renderer::create_buffers() { // 计算缓冲大小 - VkDeviceSize vertex_buffer_size = max_quads_ * 4 * sizeof(batch_vertex); - VkDeviceSize index_buffer_size = max_quads_ * 6 * sizeof(u32); + vk::DeviceSize vertex_buffer_size = max_quads_ * 4 * sizeof(batch_vertex); + vk::DeviceSize index_buffer_size = max_quads_ * 6 * sizeof(u32); // 创建顶点缓冲(GPU 本地) VkBufferCreateInfo vertex_buffer_info{}; vertex_buffer_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; vertex_buffer_info.size = vertex_buffer_size; - vertex_buffer_info.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; + vertex_buffer_info.usage = static_cast(vk::BufferUsageFlagBits::eVertexBuffer | vk::BufferUsageFlagBits::eTransferDst); VmaAllocationCreateInfo vertex_alloc_info{}; vertex_alloc_info.usage = VMA_MEMORY_USAGE_GPU_ONLY; - VkResult result = vmaCreateBuffer(allocator_, &vertex_buffer_info, &vertex_alloc_info, - &vertex_buffer_, &vertex_allocation_, nullptr); - if (result != VK_SUCCESS) { - LOG_ERROR("Failed to create vertex buffer: {}", vk_result_to_string(result)); + VkBuffer vk_vertex_buffer; + auto result = static_cast(vmaCreateBuffer(allocator_, &vertex_buffer_info, &vertex_alloc_info, + &vk_vertex_buffer, &vertex_allocation_, nullptr)); + if (result != vk::Result::eSuccess) { + MILAI_LOG_ERROR("Failed to create vertex buffer: {}", vk::to_string(result)); return false; } + vertex_buffer_ = vk_vertex_buffer; // 创建索引缓冲(GPU 本地) VkBufferCreateInfo index_buffer_info{}; index_buffer_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; index_buffer_info.size = index_buffer_size; - index_buffer_info.usage = VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; + index_buffer_info.usage = static_cast(vk::BufferUsageFlagBits::eIndexBuffer | vk::BufferUsageFlagBits::eTransferDst); VmaAllocationCreateInfo index_alloc_info{}; index_alloc_info.usage = VMA_MEMORY_USAGE_GPU_ONLY; - result = vmaCreateBuffer(allocator_, &index_buffer_info, &index_alloc_info, - &index_buffer_, &index_allocation_, nullptr); - if (result != VK_SUCCESS) { - LOG_ERROR("Failed to create index buffer: {}", vk_result_to_string(result)); + VkBuffer vk_index_buffer; + result = static_cast(vmaCreateBuffer(allocator_, &index_buffer_info, &index_alloc_info, + &vk_index_buffer, &index_allocation_, nullptr)); + if (result != vk::Result::eSuccess) { + MILAI_LOG_ERROR("Failed to create index buffer: {}", vk::to_string(result)); return false; } + index_buffer_ = vk_index_buffer; // 创建暂存缓冲(CPU 可见,用于动态更新顶点数据) VkBufferCreateInfo staging_buffer_info{}; staging_buffer_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; staging_buffer_info.size = vertex_buffer_size; - staging_buffer_info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; + staging_buffer_info.usage = static_cast(vk::BufferUsageFlagBits::eTransferSrc); VmaAllocationCreateInfo staging_alloc_info{}; staging_alloc_info.usage = VMA_MEMORY_USAGE_CPU_ONLY; staging_alloc_info.flags = VMA_ALLOCATION_CREATE_MAPPED_BIT; VmaAllocationInfo staging_info{}; - result = vmaCreateBuffer(allocator_, &staging_buffer_info, &staging_alloc_info, - &staging_buffer_, &staging_allocation_, &staging_info); - if (result != VK_SUCCESS) { - LOG_ERROR("Failed to create staging buffer: {}", vk_result_to_string(result)); + VkBuffer vk_staging_buffer; + result = static_cast(vmaCreateBuffer(allocator_, &staging_buffer_info, &staging_alloc_info, + &vk_staging_buffer, &staging_allocation_, &staging_info)); + if (result != vk::Result::eSuccess) { + MILAI_LOG_ERROR("Failed to create staging buffer: {}", vk::to_string(result)); return false; } + staging_buffer_ = vk_staging_buffer; staging_mapped_data_ = staging_info.pMappedData; // 生成索引数据(预计算) @@ -653,16 +659,16 @@ bool batch_renderer::create_buffers() { VkBufferCreateInfo index_staging_info{}; index_staging_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; index_staging_info.size = index_buffer_size; - index_staging_info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; + index_staging_info.usage = static_cast(vk::BufferUsageFlagBits::eTransferSrc); VkBuffer index_staging_buffer; VmaAllocation index_staging_alloc; VmaAllocationInfo index_staging_alloc_info; - result = vmaCreateBuffer(allocator_, &index_staging_info, &staging_alloc_info, - &index_staging_buffer, &index_staging_alloc, &index_staging_alloc_info); - if (result != VK_SUCCESS) { - LOG_ERROR("Failed to create index staging buffer: {}", vk_result_to_string(result)); + result = static_cast(vmaCreateBuffer(allocator_, &index_staging_info, &staging_alloc_info, + &index_staging_buffer, &index_staging_alloc, &index_staging_alloc_info)); + if (result != vk::Result::eSuccess) { + MILAI_LOG_ERROR("Failed to create index staging buffer: {}", vk::to_string(result)); return false; } @@ -670,70 +676,65 @@ bool batch_renderer::create_buffers() { std::memcpy(index_staging_alloc_info.pMappedData, indices.data(), index_buffer_size); // 创建命令缓冲进行复制 - VkCommandPoolCreateInfo pool_info{}; - pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; - pool_info.flags = VK_COMMAND_POOL_CREATE_TRANSIENT_BIT; - pool_info.queueFamilyIndex = device_->get_queue_family_indices().graphics_family; + vk::CommandPoolCreateInfo pool_info{}; + pool_info.flags = vk::CommandPoolCreateFlagBits::eTransient; + pool_info.queueFamilyIndex = device_->get_queue_family_indices().graphics_family.value(); - VkCommandPool transfer_pool; - result = vkCreateCommandPool(device_->get_device(), &pool_info, nullptr, &transfer_pool); - if (result != VK_SUCCESS) { - LOG_ERROR("Failed to create transfer command pool"); + auto [pool_result, transfer_pool] = device_->get_device().createCommandPool(pool_info); + if (pool_result != vk::Result::eSuccess) { + MILAI_LOG_ERROR("Failed to create transfer command pool"); vmaDestroyBuffer(allocator_, index_staging_buffer, index_staging_alloc); return false; } - VkCommandBufferAllocateInfo alloc_info{}; - alloc_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; + vk::CommandBufferAllocateInfo alloc_info{}; alloc_info.commandPool = transfer_pool; - alloc_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; + alloc_info.level = vk::CommandBufferLevel::ePrimary; alloc_info.commandBufferCount = 1; - VkCommandBuffer cmd_buffer; - result = vkAllocateCommandBuffers(device_->get_device(), &alloc_info, &cmd_buffer); - if (result != VK_SUCCESS) { - LOG_ERROR("Failed to allocate transfer command buffer"); - vkDestroyCommandPool(device_->get_device(), transfer_pool, nullptr); + auto [cmd_result, cmd_buffers] = device_->get_device().allocateCommandBuffers(alloc_info); + if (cmd_result != vk::Result::eSuccess) { + MILAI_LOG_ERROR("Failed to allocate transfer command buffer"); + device_->get_device().destroyCommandPool(transfer_pool); vmaDestroyBuffer(allocator_, index_staging_buffer, index_staging_alloc); return false; } + vk::CommandBuffer cmd_buffer = cmd_buffers[0]; // 开始记录命令 - VkCommandBufferBeginInfo begin_info{}; - begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; - begin_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; + vk::CommandBufferBeginInfo begin_info{}; + begin_info.flags = vk::CommandBufferUsageFlagBits::eOneTimeSubmit; - vkBeginCommandBuffer(cmd_buffer, &begin_info); + cmd_buffer.begin(begin_info); - VkBufferCopy copy_region{}; + vk::BufferCopy copy_region{}; copy_region.srcOffset = 0; copy_region.dstOffset = 0; copy_region.size = index_buffer_size; - vkCmdCopyBuffer(cmd_buffer, index_staging_buffer, index_buffer_, 1, ©_region); + cmd_buffer.copyBuffer(index_staging_buffer, index_buffer_, 1, ©_region); - vkEndCommandBuffer(cmd_buffer); + cmd_buffer.end(); // 提交命令 - VkSubmitInfo submit_info{}; - submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; + vk::SubmitInfo submit_info{}; submit_info.commandBufferCount = 1; submit_info.pCommandBuffers = &cmd_buffer; - vkQueueSubmit(device_->get_graphics_queue(), 1, &submit_info, VK_NULL_HANDLE); - vkQueueWaitIdle(device_->get_graphics_queue()); + device_->get_graphics_queue().submit(1, &submit_info, nullptr); + device_->get_graphics_queue().waitIdle(); // 清理 - vkDestroyCommandPool(device_->get_device(), transfer_pool, nullptr); + device_->get_device().destroyCommandPool(transfer_pool); vmaDestroyBuffer(allocator_, index_staging_buffer, index_staging_alloc); - LOG_DEBUG("Batch renderer buffers created: {} vertices, {} indices", + MILAI_LOG_DEBUG("Batch renderer buffers created: {} vertices, {} indices", max_quads_ * 4, max_quads_ * 6); return true; } void batch_renderer::destroy_resources() { - if (allocator_ == VK_NULL_HANDLE) { + if (allocator_ == nullptr) { return; } @@ -744,23 +745,23 @@ void batch_renderer::destroy_resources() { pipeline_.reset(); pipeline_layout_.reset(); - if (staging_buffer_ != VK_NULL_HANDLE) { + if (staging_buffer_) { vmaDestroyBuffer(allocator_, staging_buffer_, staging_allocation_); - staging_buffer_ = VK_NULL_HANDLE; - staging_allocation_ = VK_NULL_HANDLE; + staging_buffer_ = nullptr; + staging_allocation_ = nullptr; staging_mapped_data_ = nullptr; } - if (index_buffer_ != VK_NULL_HANDLE) { + if (index_buffer_) { vmaDestroyBuffer(allocator_, index_buffer_, index_allocation_); - index_buffer_ = VK_NULL_HANDLE; - index_allocation_ = VK_NULL_HANDLE; + index_buffer_ = nullptr; + index_allocation_ = nullptr; } - if (vertex_buffer_ != VK_NULL_HANDLE) { + if (vertex_buffer_) { vmaDestroyBuffer(allocator_, vertex_buffer_, vertex_allocation_); - vertex_buffer_ = VK_NULL_HANDLE; - vertex_allocation_ = VK_NULL_HANDLE; + vertex_buffer_ = nullptr; + vertex_allocation_ = nullptr; } initialized_ = false; @@ -771,33 +772,31 @@ void batch_renderer::upload_vertices() { return; } - VkDeviceSize data_size = vertices_.size() * sizeof(batch_vertex); + vk::DeviceSize data_size = vertices_.size() * sizeof(batch_vertex); // 复制顶点数据到暂存缓冲 std::memcpy(staging_mapped_data_, vertices_.data(), data_size); // 复制到 GPU 缓冲 - VkBufferCopy copy_region{}; + vk::BufferCopy copy_region{}; copy_region.srcOffset = 0; copy_region.dstOffset = 0; copy_region.size = data_size; - vkCmdCopyBuffer(current_cmd_buffer_, staging_buffer_, vertex_buffer_, 1, ©_region); + current_cmd_buffer_.copyBuffer(staging_buffer_, vertex_buffer_, 1, ©_region); // 添加内存屏障确保复制完成 - VkMemoryBarrier2 barrier{}; - barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER_2; - barrier.srcStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT; - barrier.srcAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT; - barrier.dstStageMask = VK_PIPELINE_STAGE_2_VERTEX_INPUT_BIT; - barrier.dstAccessMask = VK_ACCESS_2_VERTEX_ATTRIBUTE_READ_BIT; + vk::MemoryBarrier2 barrier{}; + barrier.srcStageMask = vk::PipelineStageFlagBits2::eTransfer; + barrier.srcAccessMask = vk::AccessFlagBits2::eTransferWrite; + barrier.dstStageMask = vk::PipelineStageFlagBits2::eVertexInput; + barrier.dstAccessMask = vk::AccessFlagBits2::eVertexAttributeRead; - VkDependencyInfo dependency_info{}; - dependency_info.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO; + vk::DependencyInfo dependency_info{}; dependency_info.memoryBarrierCount = 1; dependency_info.pMemoryBarriers = &barrier; - vkCmdPipelineBarrier2(current_cmd_buffer_, &dependency_info); + current_cmd_buffer_.pipelineBarrier2(dependency_info); } void batch_renderer::add_quad_vertices(const batch_quad& quad) { diff --git a/src/render/batch.hpp b/src/render/batch.hpp index aa6f12e..1a70268 100644 --- a/src/render/batch.hpp +++ b/src/render/batch.hpp @@ -17,7 +17,6 @@ #include "object.hpp" #include "types.hpp" -#include #include #include #include @@ -48,11 +47,11 @@ struct batch_vertex { * @brief 获取顶点绑定描述 * @return 顶点绑定描述 */ - static VkVertexInputBindingDescription get_binding_description() { - VkVertexInputBindingDescription binding{}; + static vk::VertexInputBindingDescription get_binding_description() { + vk::VertexInputBindingDescription binding{}; binding.binding = 0; binding.stride = sizeof(batch_vertex); - binding.inputRate = VK_VERTEX_INPUT_RATE_VERTEX; + binding.inputRate = vk::VertexInputRate::eVertex; return binding; } @@ -60,31 +59,31 @@ struct batch_vertex { * @brief 获取顶点属性描述 * @return 顶点属性描述列表 */ - static std::array get_attribute_descriptions() { - std::array attributes{}; + static std::array get_attribute_descriptions() { + std::array attributes{}; // 位置 attributes[0].binding = 0; attributes[0].location = 0; - attributes[0].format = VK_FORMAT_R32G32_SFLOAT; + attributes[0].format = vk::Format::eR32G32Sfloat; attributes[0].offset = offsetof(batch_vertex, position); // UV attributes[1].binding = 0; attributes[1].location = 1; - attributes[1].format = VK_FORMAT_R32G32_SFLOAT; + attributes[1].format = vk::Format::eR32G32Sfloat; attributes[1].offset = offsetof(batch_vertex, uv); // 颜色 attributes[2].binding = 0; attributes[2].location = 2; - attributes[2].format = VK_FORMAT_R32G32B32A32_SFLOAT; + attributes[2].format = vk::Format::eR32G32B32A32Sfloat; attributes[2].offset = offsetof(batch_vertex, color); // 纹理索引 attributes[3].binding = 0; attributes[3].location = 3; - attributes[3].format = VK_FORMAT_R32_UINT; + attributes[3].format = vk::Format::eR32Uint; attributes[3].offset = offsetof(batch_vertex, texture_index); return attributes; @@ -253,14 +252,14 @@ public: * @param depth_format 深度格式 * @return 是否成功 */ - [[nodiscard]] bool initialize(VkFormat color_format, - VkFormat depth_format = VK_FORMAT_UNDEFINED); + [[nodiscard]] bool initialize(vk::Format color_format, + vk::Format depth_format = vk::Format::eUndefined); /** * @brief 开始批处理 * @param cmd_buffer 命令缓冲 */ - void begin(VkCommandBuffer cmd_buffer); + void begin(vk::CommandBuffer cmd_buffer); /** * @brief 结束批处理 @@ -367,13 +366,13 @@ public: * @param image_view 图像视图 * @param sampler 采样器 */ - void bind_texture(u32 slot, VkImageView image_view, VkSampler sampler); + void bind_texture(u32 slot, vk::ImageView image_view, vk::Sampler sampler); /** * @brief 设置描述符集(用于纹理数组) * @param descriptor_set 描述符集 */ - void set_descriptor_set(VkDescriptorSet descriptor_set); + void set_descriptor_set(vk::DescriptorSet descriptor_set); /** * @brief 获取统计信息 @@ -439,7 +438,7 @@ private: * @param depth_format 深度格式 * @return 是否成功 */ - [[nodiscard]] bool create_pipeline(VkFormat color_format, VkFormat depth_format); + [[nodiscard]] bool create_pipeline(vk::Format color_format, vk::Format depth_format); /** * @brief 创建缓冲资源 @@ -467,7 +466,7 @@ private: std::shared_ptr device_; /// VMA 分配器 - VmaAllocator allocator_ = VK_NULL_HANDLE; + VmaAllocator allocator_ = nullptr; /// 配置 batch_renderer_config config_; @@ -479,26 +478,26 @@ private: std::unique_ptr pipeline_; /// 顶点缓冲 - VkBuffer vertex_buffer_ = VK_NULL_HANDLE; - VmaAllocation vertex_allocation_ = VK_NULL_HANDLE; + vk::Buffer vertex_buffer_; + VmaAllocation vertex_allocation_ = nullptr; /// 索引缓冲 - VkBuffer index_buffer_ = VK_NULL_HANDLE; - VmaAllocation index_allocation_ = VK_NULL_HANDLE; + vk::Buffer index_buffer_; + VmaAllocation index_allocation_ = nullptr; /// 暂存缓冲(用于 CPU 端顶点数据) - VkBuffer staging_buffer_ = VK_NULL_HANDLE; - VmaAllocation staging_allocation_ = VK_NULL_HANDLE; + vk::Buffer staging_buffer_; + VmaAllocation staging_allocation_ = nullptr; void* staging_mapped_data_ = nullptr; /// 顶点数据(CPU 端) std::vector vertices_; /// 当前命令缓冲 - VkCommandBuffer current_cmd_buffer_ = VK_NULL_HANDLE; + vk::CommandBuffer current_cmd_buffer_; /// 当前描述符集 - VkDescriptorSet current_descriptor_set_ = VK_NULL_HANDLE; + vk::DescriptorSet current_descriptor_set_; /// 推送常量数据 batch_push_constants push_constants_; diff --git a/src/render/command_buffer.cpp b/src/render/command_buffer.cpp index cd6d7a9..47e3b93 100644 --- a/src/render/command_buffer.cpp +++ b/src/render/command_buffer.cpp @@ -21,28 +21,27 @@ command_pool::command_pool(std::shared_ptr device, : device_(std::move(device)) , queue_family_index_(queue_family_index) { - VkCommandPoolCreateInfo pool_info{}; - pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; - pool_info.queueFamilyIndex = queue_family_index; - pool_info.flags = 0; + vk::CommandPoolCreateInfo pool_info{}; + pool_info.setQueueFamilyIndex(queue_family_index); if (transient) { - pool_info.flags |= VK_COMMAND_POOL_CREATE_TRANSIENT_BIT; + pool_info.flags |= vk::CommandPoolCreateFlagBits::eTransient; } if (reset_individual) { - pool_info.flags |= VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; + pool_info.flags |= vk::CommandPoolCreateFlagBits::eResetCommandBuffer; } - VkResult result = vkCreateCommandPool(device_->get_device(), &pool_info, nullptr, &pool_); - if (result != VK_SUCCESS) { - LOG_ERROR("Failed to create command pool: {}", vk_result_to_string(result)); + auto [result, pool] = device_->get_device().createCommandPool(pool_info); + if (result != vk::Result::eSuccess) { + MILAI_LOG_ERROR("Failed to create command pool: {}", vk::to_string(result)); } + pool_ = pool; } command_pool::~command_pool() { - if (pool_ != VK_NULL_HANDLE && device_ && device_->is_valid()) { - vkDestroyCommandPool(device_->get_device(), pool_, nullptr); - pool_ = VK_NULL_HANDLE; + if (pool_ && device_ && device_->is_valid()) { + device_->get_device().destroyCommandPool(pool_); + pool_ = nullptr; } } @@ -51,38 +50,38 @@ command_pool::command_pool(command_pool&& other) noexcept , pool_(other.pool_) , queue_family_index_(other.queue_family_index_) { - other.pool_ = VK_NULL_HANDLE; + other.pool_ = nullptr; } command_pool& command_pool::operator=(command_pool&& other) noexcept { if (this != &other) { - if (pool_ != VK_NULL_HANDLE && device_ && device_->is_valid()) { - vkDestroyCommandPool(device_->get_device(), pool_, nullptr); + if (pool_ && device_ && device_->is_valid()) { + device_->get_device().destroyCommandPool(pool_); } device_ = std::move(other.device_); pool_ = other.pool_; queue_family_index_ = other.queue_family_index_; - other.pool_ = VK_NULL_HANDLE; + other.pool_ = nullptr; } return *this; } void command_pool::on_created() { - LOG_DEBUG("Command pool created for queue family {}", queue_family_index_); + MILAI_LOG_DEBUG("Command pool created for queue family {}", queue_family_index_); } void command_pool::on_destroying() { - LOG_DEBUG("Command pool destroying"); + MILAI_LOG_DEBUG("Command pool destroying"); } -std::unique_ptr command_pool::allocate_buffer(VkCommandBufferLevel level) { +std::unique_ptr command_pool::allocate_buffer(vk::CommandBufferLevel level) { return std::make_unique(*this, level); } std::vector> command_pool::allocate_buffers( - u32 count, VkCommandBufferLevel level) + u32 count, vk::CommandBufferLevel level) { std::vector> buffers; buffers.reserve(count); @@ -94,97 +93,95 @@ std::vector> command_pool::allocate_buffers( return buffers; } -VkCommandBuffer command_pool::allocate_raw(VkCommandBufferLevel level) { - VkCommandBufferAllocateInfo alloc_info{}; - alloc_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; - alloc_info.commandPool = pool_; - alloc_info.level = level; - alloc_info.commandBufferCount = 1; +vk::CommandBuffer command_pool::allocate_raw(vk::CommandBufferLevel level) { + vk::CommandBufferAllocateInfo alloc_info{}; + alloc_info.setCommandPool(pool_) + .setLevel(level) + .setCommandBufferCount(1); - VkCommandBuffer buffer = VK_NULL_HANDLE; - VkResult result = vkAllocateCommandBuffers(device_->get_device(), &alloc_info, &buffer); - if (result != VK_SUCCESS) { - LOG_ERROR("Failed to allocate command buffer: {}", vk_result_to_string(result)); - return VK_NULL_HANDLE; + auto [result, buffers] = device_->get_device().allocateCommandBuffers(alloc_info); + if (result != vk::Result::eSuccess) { + MILAI_LOG_ERROR("Failed to allocate command buffer: {}", vk::to_string(result)); + return {}; } - return buffer; + return buffers[0]; } -std::vector command_pool::allocate_raw_buffers(u32 count, VkCommandBufferLevel level) { - VkCommandBufferAllocateInfo alloc_info{}; - alloc_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; - alloc_info.commandPool = pool_; - alloc_info.level = level; - alloc_info.commandBufferCount = count; +std::vector command_pool::allocate_raw_buffers(u32 count, vk::CommandBufferLevel level) { + vk::CommandBufferAllocateInfo alloc_info{}; + alloc_info.setCommandPool(pool_) + .setLevel(level) + .setCommandBufferCount(count); - std::vector buffers(count); - VkResult result = vkAllocateCommandBuffers(device_->get_device(), &alloc_info, buffers.data()); - if (result != VK_SUCCESS) { - LOG_ERROR("Failed to allocate command buffers: {}", vk_result_to_string(result)); + auto [result, buffers] = device_->get_device().allocateCommandBuffers(alloc_info); + if (result != vk::Result::eSuccess) { + MILAI_LOG_ERROR("Failed to allocate command buffers: {}", vk::to_string(result)); return {}; } return buffers; } -void command_pool::free_raw(VkCommandBuffer buffer) { - if (buffer != VK_NULL_HANDLE) { - vkFreeCommandBuffers(device_->get_device(), pool_, 1, &buffer); +void command_pool::free_raw(vk::CommandBuffer buffer) { + if (buffer) { + device_->get_device().freeCommandBuffers(pool_, buffer); } } -void command_pool::free_raw_buffers(std::span buffers) { +void command_pool::free_raw_buffers(std::span buffers) { if (!buffers.empty()) { - vkFreeCommandBuffers(device_->get_device(), pool_, - static_cast(buffers.size()), buffers.data()); + device_->get_device().freeCommandBuffers(pool_, buffers.size(), buffers.data()); } } void command_pool::reset(bool release_resources) { - VkCommandPoolResetFlags flags = 0; + vk::CommandPoolResetFlags flags; if (release_resources) { - flags |= VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT; + flags |= vk::CommandPoolResetFlagBits::eReleaseResources; } - vkResetCommandPool(device_->get_device(), pool_, flags); + device_->get_device().resetCommandPool(pool_, flags); } // ================================================================================================ // command_buffer 实现 // ================================================================================================ -command_buffer::command_buffer(command_pool& pool, VkCommandBufferLevel level) +command_buffer::command_buffer(command_pool& pool, vk::CommandBufferLevel level) : device_(pool.get_device()) , pool_(&pool) , level_(level) { - VkCommandBufferAllocateInfo alloc_info{}; - alloc_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; - alloc_info.commandPool = pool.get_vulkan_pool(); - alloc_info.level = level; - alloc_info.commandBufferCount = 1; + vk::CommandBufferAllocateInfo alloc_info{}; + alloc_info.setCommandPool(pool.get_vulkan_pool()) + .setLevel(level) + .setCommandBufferCount(1); - VkResult result = vkAllocateCommandBuffers(device_->get_device(), &alloc_info, &buffer_); - if (result != VK_SUCCESS) { - LOG_ERROR("Failed to allocate command buffer: {}", vk_result_to_string(result)); + auto [result, buffers] = device_->get_device().allocateCommandBuffers(alloc_info); + if (result != vk::Result::eSuccess) { + MILAI_LOG_ERROR("Failed to allocate command buffer: {}", vk::to_string(result)); + } else { + buffer_ = buffers[0]; } } command_buffer::command_buffer(std::shared_ptr device, - VkCommandBuffer buffer, - VkCommandBufferLevel level) + vk::CommandBuffer buffer, + vk::CommandBufferLevel level) : device_(std::move(device)) + , pool_(nullptr) , buffer_(buffer) , level_(level) + , recording_(false) , owns_buffer_(false) { } command_buffer::~command_buffer() { - if (owns_buffer_ && buffer_ != VK_NULL_HANDLE && pool_ != nullptr) { - vkFreeCommandBuffers(device_->get_device(), pool_->get_vulkan_pool(), 1, &buffer_); - buffer_ = VK_NULL_HANDLE; + if (owns_buffer_ && buffer_ && pool_ != nullptr) { + device_->get_device().freeCommandBuffers(pool_->get_vulkan_pool(), buffer_); + buffer_ = nullptr; } } @@ -196,15 +193,15 @@ command_buffer::command_buffer(command_buffer&& other) noexcept , recording_(other.recording_) , owns_buffer_(other.owns_buffer_) { - other.buffer_ = VK_NULL_HANDLE; + other.buffer_ = nullptr; other.pool_ = nullptr; other.recording_ = false; } command_buffer& command_buffer::operator=(command_buffer&& other) noexcept { if (this != &other) { - if (owns_buffer_ && buffer_ != VK_NULL_HANDLE && pool_ != nullptr) { - vkFreeCommandBuffers(device_->get_device(), pool_->get_vulkan_pool(), 1, &buffer_); + if (owns_buffer_ && buffer_ && pool_ != nullptr) { + device_->get_device().freeCommandBuffers(pool_->get_vulkan_pool(), buffer_); } device_ = std::move(other.device_); @@ -214,7 +211,7 @@ command_buffer& command_buffer::operator=(command_buffer&& other) noexcept { recording_ = other.recording_; owns_buffer_ = other.owns_buffer_; - other.buffer_ = VK_NULL_HANDLE; + other.buffer_ = nullptr; other.pool_ = nullptr; other.recording_ = false; } @@ -222,28 +219,27 @@ command_buffer& command_buffer::operator=(command_buffer&& other) noexcept { } void command_buffer::on_created() { - LOG_DEBUG("Command buffer created"); + MILAI_LOG_DEBUG("Command buffer created"); } void command_buffer::on_destroying() { - LOG_DEBUG("Command buffer destroying"); + MILAI_LOG_DEBUG("Command buffer destroying"); } // ================================================================================================ // 录制控制 // ================================================================================================ -void command_buffer::begin(VkCommandBufferUsageFlags flags, - const VkCommandBufferInheritanceInfo* inheritance_info) +void command_buffer::begin(vk::CommandBufferUsageFlags flags, + const vk::CommandBufferInheritanceInfo* inheritance_info) { - VkCommandBufferBeginInfo begin_info{}; - begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; - begin_info.flags = flags; - begin_info.pInheritanceInfo = inheritance_info; + vk::CommandBufferBeginInfo begin_info{}; + begin_info.setFlags(flags) + .setPInheritanceInfo(inheritance_info); - VkResult result = vkBeginCommandBuffer(buffer_, &begin_info); - if (result != VK_SUCCESS) { - LOG_ERROR("Failed to begin command buffer: {}", vk_result_to_string(result)); + vk::Result result = buffer_.begin(&begin_info); + if (result != vk::Result::eSuccess) { + MILAI_LOG_ERROR("Failed to begin command buffer: {}", vk::to_string(result)); return; } @@ -251,25 +247,25 @@ void command_buffer::begin(VkCommandBufferUsageFlags flags, } void command_buffer::begin_one_time() { - begin(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT); + begin(vk::CommandBufferUsageFlagBits::eOneTimeSubmit); } void command_buffer::end() { - VkResult result = vkEndCommandBuffer(buffer_); - if (result != VK_SUCCESS) { - LOG_ERROR("Failed to end command buffer: {}", vk_result_to_string(result)); + vk::Result result = buffer_.end(); + if (result != vk::Result::eSuccess) { + MILAI_LOG_ERROR("Failed to end command buffer: {}", vk::to_string(result)); } recording_ = false; } void command_buffer::reset(bool release_resources) { - VkCommandBufferResetFlags flags = 0; + vk::CommandBufferResetFlags flags; if (release_resources) { - flags |= VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT; + flags |= vk::CommandBufferResetFlagBits::eReleaseResources; } - vkResetCommandBuffer(buffer_, flags); + buffer_.reset(flags); recording_ = false; } @@ -278,7 +274,7 @@ void command_buffer::reset(bool release_resources) { // ================================================================================================ void command_buffer::begin_rendering( - VkRect2D render_area, + vk::Rect2D render_area, std::span color_attachments, const depth_attachment_info* depth_attachment, const depth_attachment_info* stencil_attachment, @@ -286,113 +282,114 @@ void command_buffer::begin_rendering( u32 view_mask) { // 转换颜色附件 - std::vector vk_color_attachments; + std::vector vk_color_attachments; vk_color_attachments.reserve(color_attachments.size()); for (const auto& attachment : color_attachments) { vk_color_attachments.push_back(attachment.to_vulkan()); } // 转换深度附件 - VkRenderingAttachmentInfo vk_depth_attachment{}; + vk::RenderingAttachmentInfo vk_depth_attachment{}; if (depth_attachment != nullptr) { vk_depth_attachment = depth_attachment->to_vulkan(); } // 转换模板附件 - VkRenderingAttachmentInfo vk_stencil_attachment{}; + vk::RenderingAttachmentInfo vk_stencil_attachment{}; if (stencil_attachment != nullptr) { vk_stencil_attachment = stencil_attachment->to_vulkan(); } - VkRenderingInfo rendering_info{}; - rendering_info.sType = VK_STRUCTURE_TYPE_RENDERING_INFO; - rendering_info.renderArea = render_area; - rendering_info.layerCount = layer_count; - rendering_info.viewMask = view_mask; - rendering_info.colorAttachmentCount = static_cast(vk_color_attachments.size()); - rendering_info.pColorAttachments = vk_color_attachments.data(); - rendering_info.pDepthAttachment = depth_attachment != nullptr ? &vk_depth_attachment : nullptr; - rendering_info.pStencilAttachment = stencil_attachment != nullptr ? &vk_stencil_attachment : nullptr; + vk::RenderingInfo rendering_info{}; + rendering_info.setRenderArea(render_area) + .setLayerCount(layer_count) + .setViewMask(view_mask) + .setColorAttachments(vk_color_attachments); - vkCmdBeginRendering(buffer_, &rendering_info); + if (depth_attachment) { + rendering_info.setPDepthAttachment(&vk_depth_attachment); + } + if (stencil_attachment) { + rendering_info.setPStencilAttachment(&vk_stencil_attachment); + } + + buffer_.beginRendering(rendering_info); } void command_buffer::begin_rendering( - VkExtent2D extent, + vk::Extent2D extent, std::span color_attachments, const depth_attachment_info* depth_attachment) { - VkRect2D render_area{}; - render_area.offset = {0, 0}; + vk::Rect2D render_area{}; + render_area.offset = vk::Offset2D{0, 0}; render_area.extent = extent; begin_rendering(render_area, color_attachments, depth_attachment, nullptr, 1, 0); } void command_buffer::end_rendering() { - vkCmdEndRendering(buffer_); + buffer_.endRendering(); } // ================================================================================================ // 管线绑定 // ================================================================================================ -void command_buffer::bind_pipeline(VkPipelineBindPoint bind_point, VkPipeline pipeline) { - vkCmdBindPipeline(buffer_, bind_point, pipeline); +void command_buffer::bind_pipeline(vk::PipelineBindPoint bind_point, vk::Pipeline pipeline) { + buffer_.bindPipeline(bind_point, pipeline); } void command_buffer::bind_vertex_buffers(u32 first_binding, - std::span buffers, - std::span offsets) + std::span buffers, + std::span offsets) { - vkCmdBindVertexBuffers(buffer_, first_binding, - static_cast(buffers.size()), - buffers.data(), offsets.data()); + buffer_.bindVertexBuffers(first_binding, buffers.size(), buffers.data(), offsets.data()); } -void command_buffer::bind_vertex_buffer(u32 binding, VkBuffer buffer, VkDeviceSize offset) { - vkCmdBindVertexBuffers(buffer_, binding, 1, &buffer, &offset); +void command_buffer::bind_vertex_buffer(u32 binding, vk::Buffer buffer, vk::DeviceSize offset) { + buffer_.bindVertexBuffers(binding, 1, &buffer, &offset); } -void command_buffer::bind_index_buffer(VkBuffer buffer, VkDeviceSize offset, VkIndexType index_type) { - vkCmdBindIndexBuffer(buffer_, buffer, offset, index_type); +void command_buffer::bind_index_buffer(vk::Buffer buffer, vk::DeviceSize offset, vk::IndexType index_type) { + buffer_.bindIndexBuffer(buffer, offset, index_type); } -void command_buffer::bind_descriptor_sets(VkPipelineBindPoint bind_point, - VkPipelineLayout layout, +void command_buffer::bind_descriptor_sets(vk::PipelineBindPoint bind_point, + vk::PipelineLayout layout, u32 first_set, - std::span descriptor_sets, + std::span descriptor_sets, std::span dynamic_offsets) { - vkCmdBindDescriptorSets(buffer_, bind_point, layout, first_set, - static_cast(descriptor_sets.size()), descriptor_sets.data(), - static_cast(dynamic_offsets.size()), dynamic_offsets.data()); + buffer_.bindDescriptorSets(bind_point, layout, first_set, + descriptor_sets.size(), descriptor_sets.data(), + dynamic_offsets.size(), dynamic_offsets.data()); } // ================================================================================================ // 绘制命令 // ================================================================================================ -void command_buffer::draw(u32 vertex_count, u32 instance_count, +void command_buffer::draw(u32 vertex_count, u32 instance_count, u32 first_vertex, u32 first_instance) { - vkCmdDraw(buffer_, vertex_count, instance_count, first_vertex, first_instance); + buffer_.draw(vertex_count, instance_count, first_vertex, first_instance); } void command_buffer::draw_indexed(u32 index_count, u32 instance_count, u32 first_index, i32 vertex_offset, u32 first_instance) { - vkCmdDrawIndexed(buffer_, index_count, instance_count, first_index, vertex_offset, first_instance); + buffer_.drawIndexed(index_count, instance_count, first_index, vertex_offset, first_instance); } -void command_buffer::draw_indirect(VkBuffer buffer, VkDeviceSize offset, u32 draw_count, u32 stride) { - vkCmdDrawIndirect(buffer_, buffer, offset, draw_count, stride); +void command_buffer::draw_indirect(vk::Buffer buffer, vk::DeviceSize offset, u32 draw_count, u32 stride) { + buffer_.drawIndirect(buffer, offset, draw_count, stride); } -void command_buffer::draw_indexed_indirect(VkBuffer buffer, VkDeviceSize offset, +void command_buffer::draw_indexed_indirect(vk::Buffer buffer, vk::DeviceSize offset, u32 draw_count, u32 stride) { - vkCmdDrawIndexedIndirect(buffer_, buffer, offset, draw_count, stride); + buffer_.drawIndexedIndirect(buffer, offset, draw_count, stride); } // ================================================================================================ @@ -400,63 +397,57 @@ void command_buffer::draw_indexed_indirect(VkBuffer buffer, VkDeviceSize offset, // ================================================================================================ void command_buffer::dispatch(u32 group_count_x, u32 group_count_y, u32 group_count_z) { - vkCmdDispatch(buffer_, group_count_x, group_count_y, group_count_z); + buffer_.dispatch(group_count_x, group_count_y, group_count_z); } -void command_buffer::dispatch_indirect(VkBuffer buffer, VkDeviceSize offset) { - vkCmdDispatchIndirect(buffer_, buffer, offset); +void command_buffer::dispatch_indirect(vk::Buffer buffer, vk::DeviceSize offset) { + buffer_.dispatchIndirect(buffer, offset); } // ================================================================================================ // 同步命令(Synchronization2) // ================================================================================================ -void command_buffer::pipeline_barrier(const VkDependencyInfo& dependency_info) { - vkCmdPipelineBarrier2(buffer_, &dependency_info); +void command_buffer::pipeline_barrier(const vk::DependencyInfo& dependency_info) { + buffer_.pipelineBarrier2(dependency_info); } void command_buffer::memory_barrier(const memory_barrier_config& config) { - VkMemoryBarrier2 barrier{}; - barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER_2; - barrier.srcStageMask = config.src_stage_mask; - barrier.srcAccessMask = config.src_access_mask; - barrier.dstStageMask = config.dst_stage_mask; - barrier.dstAccessMask = config.dst_access_mask; + vk::MemoryBarrier2 barrier{}; + barrier.setSrcStageMask(static_cast(config.src_stage_mask)) + .setSrcAccessMask(static_cast(config.src_access_mask)) + .setDstStageMask(static_cast(config.dst_stage_mask)) + .setDstAccessMask(static_cast(config.dst_access_mask)); - VkDependencyInfo dependency_info{}; - dependency_info.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO; - dependency_info.memoryBarrierCount = 1; - dependency_info.pMemoryBarriers = &barrier; + vk::DependencyInfo dependency_info{}; + dependency_info.setMemoryBarriers(barrier); - vkCmdPipelineBarrier2(buffer_, &dependency_info); + buffer_.pipelineBarrier2(dependency_info); } void command_buffer::image_barrier(const image_memory_barrier_config& config) { - VkImageMemoryBarrier2 barrier{}; - barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2; - barrier.srcStageMask = config.src_stage_mask; - barrier.srcAccessMask = config.src_access_mask; - barrier.dstStageMask = config.dst_stage_mask; - barrier.dstAccessMask = config.dst_access_mask; - barrier.oldLayout = config.old_layout; - barrier.newLayout = config.new_layout; - barrier.srcQueueFamilyIndex = config.src_queue_family_index; - barrier.dstQueueFamilyIndex = config.dst_queue_family_index; - barrier.image = config.image; - barrier.subresourceRange = config.subresource_range; + vk::ImageMemoryBarrier2 barrier{}; + barrier.setSrcStageMask(static_cast(config.src_stage_mask)) + .setSrcAccessMask(static_cast(config.src_access_mask)) + .setDstStageMask(static_cast(config.dst_stage_mask)) + .setDstAccessMask(static_cast(config.dst_access_mask)) + .setOldLayout(static_cast(config.old_layout)) + .setNewLayout(static_cast(config.new_layout)) + .setSrcQueueFamilyIndex(config.src_queue_family_index) + .setDstQueueFamilyIndex(config.dst_queue_family_index) + .setImage(config.image) + .setSubresourceRange(config.subresource_range); - VkDependencyInfo dependency_info{}; - dependency_info.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO; - dependency_info.imageMemoryBarrierCount = 1; - dependency_info.pImageMemoryBarriers = &barrier; + vk::DependencyInfo dependency_info{}; + dependency_info.setImageMemoryBarriers(barrier); - vkCmdPipelineBarrier2(buffer_, &dependency_info); + buffer_.pipelineBarrier2(dependency_info); } -void command_buffer::transition_image_layout(VkImage image, - VkImageLayout old_layout, - VkImageLayout new_layout, - const VkImageSubresourceRange& subresource_range) +void command_buffer::transition_image_layout(vk::Image image, + vk::ImageLayout old_layout, + vk::ImageLayout new_layout, + const vk::ImageSubresourceRange& subresource_range) { image_memory_barrier_config config; config.image = image; @@ -465,44 +456,43 @@ void command_buffer::transition_image_layout(VkImage image, config.subresource_range = subresource_range; // 设置适当的阶段和访问掩码 - if (old_layout == VK_IMAGE_LAYOUT_UNDEFINED && - new_layout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) { - config.src_stage_mask = VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT; - config.src_access_mask = VK_ACCESS_2_NONE; - config.dst_stage_mask = VK_PIPELINE_STAGE_2_TRANSFER_BIT; - config.dst_access_mask = VK_ACCESS_2_TRANSFER_WRITE_BIT; - } else if (old_layout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL && - new_layout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) { - config.src_stage_mask = VK_PIPELINE_STAGE_2_TRANSFER_BIT; - config.src_access_mask = VK_ACCESS_2_TRANSFER_WRITE_BIT; - config.dst_stage_mask = VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT; - config.dst_access_mask = VK_ACCESS_2_SHADER_READ_BIT; - } else if (old_layout == VK_IMAGE_LAYOUT_UNDEFINED && - new_layout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) { - config.src_stage_mask = VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT; - config.src_access_mask = VK_ACCESS_2_NONE; - config.dst_stage_mask = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT; - config.dst_access_mask = VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT; - } else if (old_layout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL && - new_layout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR) { - config.src_stage_mask = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT; - config.src_access_mask = VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT; - config.dst_stage_mask = VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT; - config.dst_access_mask = VK_ACCESS_2_NONE; + if (old_layout == vk::ImageLayout::eUndefined && + new_layout == vk::ImageLayout::eTransferDstOptimal) { + config.src_stage_mask = vk::PipelineStageFlagBits2::eTopOfPipe; + config.src_access_mask = vk::AccessFlagBits2::eNone; + config.dst_stage_mask = vk::PipelineStageFlagBits2::eTransfer; + config.dst_access_mask = vk::AccessFlagBits2::eTransferWrite; + } else if (old_layout == vk::ImageLayout::eTransferDstOptimal && + new_layout == vk::ImageLayout::eShaderReadOnlyOptimal) { + config.src_stage_mask = vk::PipelineStageFlagBits2::eTransfer; + config.src_access_mask = vk::AccessFlagBits2::eTransferWrite; + config.dst_stage_mask = vk::PipelineStageFlagBits2::eFragmentShader; + config.dst_access_mask = vk::AccessFlagBits2::eShaderRead; + } else if (old_layout == vk::ImageLayout::eUndefined && + new_layout == vk::ImageLayout::eColorAttachmentOptimal) { + config.src_stage_mask = vk::PipelineStageFlagBits2::eTopOfPipe; + config.src_access_mask = vk::AccessFlagBits2::eNone; + config.dst_stage_mask = vk::PipelineStageFlagBits2::eColorAttachmentOutput; + config.dst_access_mask = vk::AccessFlagBits2::eColorAttachmentWrite; + } else if (old_layout == vk::ImageLayout::eColorAttachmentOptimal && + new_layout == vk::ImageLayout::ePresentSrcKHR) { + config.src_stage_mask = vk::PipelineStageFlagBits2::eColorAttachmentOutput; + config.src_access_mask = vk::AccessFlagBits2::eColorAttachmentWrite; + config.dst_stage_mask = vk::PipelineStageFlagBits2::eBottomOfPipe; + config.dst_access_mask = vk::AccessFlagBits2::eNone; } else { // 通用过渡 - config.src_stage_mask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT; - config.src_access_mask = VK_ACCESS_2_MEMORY_WRITE_BIT; - config.dst_stage_mask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT; - config.dst_access_mask = VK_ACCESS_2_MEMORY_READ_BIT | VK_ACCESS_2_MEMORY_WRITE_BIT; + config.src_stage_mask = vk::PipelineStageFlagBits2::eAllCommands; + config.src_access_mask = vk::AccessFlagBits2::eMemoryWrite; + config.dst_stage_mask = vk::PipelineStageFlagBits2::eAllCommands; + config.dst_access_mask = vk::AccessFlagBits2::eMemoryRead | vk::AccessFlagBits2::eMemoryWrite; } image_barrier(config); } void command_buffer::buffer_barrier(const buffer_memory_barrier_config& config) { - VkBufferMemoryBarrier2 barrier{}; - barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2; + vk::BufferMemoryBarrier2 barrier{}; barrier.srcStageMask = config.src_stage_mask; barrier.srcAccessMask = config.src_access_mask; barrier.dstStageMask = config.dst_stage_mask; @@ -513,79 +503,74 @@ void command_buffer::buffer_barrier(const buffer_memory_barrier_config& config) barrier.offset = config.offset; barrier.size = config.size; - VkDependencyInfo dependency_info{}; - dependency_info.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO; - dependency_info.bufferMemoryBarrierCount = 1; - dependency_info.pBufferMemoryBarriers = &barrier; + vk::DependencyInfo dependency_info{}; + dependency_info.setBufferMemoryBarriers(barrier); - vkCmdPipelineBarrier2(buffer_, &dependency_info); + buffer_.pipelineBarrier2(dependency_info); } // ================================================================================================ // 复制命令 // ================================================================================================ -void command_buffer::copy_buffer(VkBuffer src, VkBuffer dst, - std::span regions) +void command_buffer::copy_buffer(vk::Buffer src, vk::Buffer dst, + std::span regions) { - vkCmdCopyBuffer(buffer_, src, dst, static_cast(regions.size()), regions.data()); + buffer_.copyBuffer(src, dst, regions); } -void command_buffer::copy_buffer(VkBuffer src, VkBuffer dst, VkDeviceSize size, - VkDeviceSize src_offset, VkDeviceSize dst_offset) +void command_buffer::copy_buffer(vk::Buffer src, vk::Buffer dst, vk::DeviceSize size, + vk::DeviceSize src_offset, vk::DeviceSize dst_offset) { - VkBufferCopy region{}; + vk::BufferCopy region{}; region.srcOffset = src_offset; region.dstOffset = dst_offset; region.size = size; - vkCmdCopyBuffer(buffer_, src, dst, 1, ®ion); + buffer_.copyBuffer(src, dst, region); } -void command_buffer::copy_image(VkImage src, VkImageLayout src_layout, - VkImage dst, VkImageLayout dst_layout, - std::span regions) +void command_buffer::copy_image(vk::Image src, vk::ImageLayout src_layout, + vk::Image dst, vk::ImageLayout dst_layout, + std::span regions) { - vkCmdCopyImage(buffer_, src, src_layout, dst, dst_layout, - static_cast(regions.size()), regions.data()); + buffer_.copyImage(src, src_layout, dst, dst_layout, regions); } -void command_buffer::copy_buffer_to_image(VkBuffer src, VkImage dst, VkImageLayout dst_layout, - std::span regions) +void command_buffer::copy_buffer_to_image(vk::Buffer src, vk::Image dst, vk::ImageLayout dst_layout, + std::span regions) { - vkCmdCopyBufferToImage(buffer_, src, dst, dst_layout, - static_cast(regions.size()), regions.data()); + buffer_.copyBufferToImage(src, dst, dst_layout, regions); } -void command_buffer::copy_image_to_buffer(VkImage src, VkImageLayout src_layout, VkBuffer dst, - std::span regions) +void command_buffer::copy_image_to_buffer(vk::Image src, vk::ImageLayout src_layout, vk::Buffer dst, + std::span regions) { - vkCmdCopyImageToBuffer(buffer_, src, src_layout, dst, - static_cast(regions.size()), regions.data()); + buffer_.copyImageToBuffer(src, src_layout, dst, regions); } // ================================================================================================ // 推送常量 // ================================================================================================ -void command_buffer::push_constants(VkPipelineLayout layout, VkShaderStageFlags stage_flags, +void command_buffer::push_constants(vk::PipelineLayout layout, vk::ShaderStageFlags stage_flags, u32 offset, u32 size, const void* data) { - vkCmdPushConstants(buffer_, layout, stage_flags, offset, size, data); + buffer_.pushConstants(layout, stage_flags, offset, size, data); } // ================================================================================================ // 视口和裁剪 // ================================================================================================ -void command_buffer::set_viewport(u32 first_viewport, std::span viewports) { - vkCmdSetViewport(buffer_, first_viewport, static_cast(viewports.size()), viewports.data()); +void command_buffer::set_viewport(u32 first_viewport, std::span viewports) { + buffer_.setViewport(first_viewport, viewports); } -void command_buffer::set_viewport(f32 x, f32 y, f32 width, f32 height, +void command_buffer::set_viewport(f32 x, f32 y, f32 width, f32 height, f32 min_depth, f32 max_depth) { - VkViewport viewport{}; + vk::Viewport viewport{}; viewport.x = x; viewport.y = y; viewport.width = width; @@ -593,47 +578,45 @@ void command_buffer::set_viewport(f32 x, f32 y, f32 width, f32 height, viewport.minDepth = min_depth; viewport.maxDepth = max_depth; - vkCmdSetViewport(buffer_, 0, 1, &viewport); + buffer_.setViewport(0, viewport); } -void command_buffer::set_scissor(u32 first_scissor, std::span scissors) { - vkCmdSetScissor(buffer_, first_scissor, static_cast(scissors.size()), scissors.data()); +void command_buffer::set_scissor(u32 first_scissor, std::span scissors) { + buffer_.setScissor(first_scissor, scissors); } void command_buffer::set_scissor(i32 x, i32 y, u32 width, u32 height) { - VkRect2D scissor{}; - scissor.offset = {x, y}; - scissor.extent = {width, height}; + vk::Rect2D scissor{}; + scissor.offset = vk::Offset2D{x, y}; + scissor.extent = vk::Extent2D{width, height}; - vkCmdSetScissor(buffer_, 0, 1, &scissor); + buffer_.setScissor(0, scissor); } // ================================================================================================ // 其他命令 // ================================================================================================ -void command_buffer::clear_color_image(VkImage image, VkImageLayout layout, - const VkClearColorValue& clear_color, - std::span ranges) +void command_buffer::clear_color_image(vk::Image image, vk::ImageLayout layout, + const vk::ClearColorValue& clear_color, + std::span ranges) { - vkCmdClearColorImage(buffer_, image, layout, &clear_color, - static_cast(ranges.size()), ranges.data()); + buffer_.clearColorImage(image, layout, clear_color, ranges); } -void command_buffer::clear_depth_stencil_image(VkImage image, VkImageLayout layout, - const VkClearDepthStencilValue& clear_value, - std::span ranges) +void command_buffer::clear_depth_stencil_image(vk::Image image, vk::ImageLayout layout, + const vk::ClearDepthStencilValue& clear_value, + std::span ranges) { - vkCmdClearDepthStencilImage(buffer_, image, layout, &clear_value, - static_cast(ranges.size()), ranges.data()); + buffer_.clearDepthStencilImage(image, layout, clear_value, ranges); } -void command_buffer::fill_buffer(VkBuffer buffer, VkDeviceSize offset, VkDeviceSize size, u32 data) { - vkCmdFillBuffer(buffer_, buffer, offset, size, data); +void command_buffer::fill_buffer(vk::Buffer buffer, vk::DeviceSize offset, vk::DeviceSize size, u32 data) { + buffer_.fillBuffer(buffer, offset, size, data); } -void command_buffer::execute_commands(std::span command_buffers) { - vkCmdExecuteCommands(buffer_, static_cast(command_buffers.size()), command_buffers.data()); +void command_buffer::execute_commands(std::span command_buffers) { + buffer_.executeCommands(command_buffers); } } // namespace milai \ No newline at end of file diff --git a/src/render/command_buffer.hpp b/src/render/command_buffer.hpp index 2268487..4dd9769 100644 --- a/src/render/command_buffer.hpp +++ b/src/render/command_buffer.hpp @@ -18,8 +18,11 @@ #include "vulkan_device.hpp" #include "object.hpp" +#define VULKAN_HPP_NO_EXCEPTIONS +#include #include #include +#include namespace milai { @@ -93,7 +96,7 @@ public: * @return 命令缓冲 */ [[nodiscard]] std::unique_ptr allocate_buffer( - VkCommandBufferLevel level = VK_COMMAND_BUFFER_LEVEL_PRIMARY); + vk::CommandBufferLevel level = vk::CommandBufferLevel::ePrimary); /** * @brief 批量分配命令缓冲 @@ -103,37 +106,37 @@ public: */ [[nodiscard]] std::vector> allocate_buffers( u32 count, - VkCommandBufferLevel level = VK_COMMAND_BUFFER_LEVEL_PRIMARY); + vk::CommandBufferLevel level = vk::CommandBufferLevel::ePrimary); /** * @brief 分配原始 Vulkan 命令缓冲 * @param level 命令缓冲级别 - * @return VkCommandBuffer 句柄 + * @return vk::CommandBuffer 句柄 */ - [[nodiscard]] VkCommandBuffer allocate_raw( - VkCommandBufferLevel level = VK_COMMAND_BUFFER_LEVEL_PRIMARY); + [[nodiscard]] vk::CommandBuffer allocate_raw( + vk::CommandBufferLevel level = vk::CommandBufferLevel::ePrimary); /** * @brief 批量分配原始 Vulkan 命令缓冲 * @param count 数量 * @param level 命令缓冲级别 - * @return VkCommandBuffer 句柄列表 + * @return vk::CommandBuffer 句柄列表 */ - [[nodiscard]] std::vector allocate_raw_buffers( + [[nodiscard]] std::vector allocate_raw_buffers( u32 count, - VkCommandBufferLevel level = VK_COMMAND_BUFFER_LEVEL_PRIMARY); + vk::CommandBufferLevel level = vk::CommandBufferLevel::ePrimary); /** * @brief 释放原始命令缓冲 * @param buffer 命令缓冲句柄 */ - void free_raw(VkCommandBuffer buffer); + void free_raw(vk::CommandBuffer buffer); /** * @brief 批量释放原始命令缓冲 * @param buffers 命令缓冲句柄列表 */ - void free_raw_buffers(std::span buffers); + void free_raw_buffers(std::span buffers); // ============================================================================================ // 池操作 @@ -151,9 +154,9 @@ public: /** * @brief 获取命令池句柄 - * @return VkCommandPool 句柄 + * @return vk::CommandPool 句柄 */ - [[nodiscard]] VkCommandPool get_vulkan_pool() const noexcept { + [[nodiscard]] vk::CommandPool get_vulkan_pool() const noexcept { return pool_; } @@ -162,7 +165,7 @@ public: * @return 如果有效返回 true */ [[nodiscard]] bool is_valid() const noexcept { - return pool_ != VK_NULL_HANDLE; + return !!pool_; } /** @@ -190,7 +193,7 @@ private: std::shared_ptr device_; /// 命令池句柄 - VkCommandPool pool_ = VK_NULL_HANDLE; + vk::CommandPool pool_; /// 队列族索引 u32 queue_family_index_ = 0; @@ -239,8 +242,8 @@ public: * @param pool 命令池 * @param level 命令缓冲级别 */ - command_buffer(command_pool& pool, - VkCommandBufferLevel level = VK_COMMAND_BUFFER_LEVEL_PRIMARY); + command_buffer(command_pool& pool, + vk::CommandBufferLevel level = vk::CommandBufferLevel::ePrimary); /** * @brief 构造函数(使用原始句柄) @@ -249,8 +252,8 @@ public: * @param level 命令缓冲级别 */ command_buffer(std::shared_ptr device, - VkCommandBuffer buffer, - VkCommandBufferLevel level = VK_COMMAND_BUFFER_LEVEL_PRIMARY); + vk::CommandBuffer buffer, + vk::CommandBufferLevel level = vk::CommandBufferLevel::ePrimary); /** * @brief 析构函数 @@ -274,8 +277,8 @@ public: * @param flags 使用标志 * @param inheritance_info 继承信息(用于二级命令缓冲) */ - void begin(VkCommandBufferUsageFlags flags = 0, - const VkCommandBufferInheritanceInfo* inheritance_info = nullptr); + void begin(vk::CommandBufferUsageFlags flags = {}, + const vk::CommandBufferInheritanceInfo* inheritance_info = nullptr); /** * @brief 开始一次性录制 @@ -315,7 +318,7 @@ public: * @param view_mask 视图掩码 */ void begin_rendering( - VkRect2D render_area, + vk::Rect2D render_area, std::span color_attachments, const depth_attachment_info* depth_attachment = nullptr, const depth_attachment_info* stencil_attachment = nullptr, @@ -329,7 +332,7 @@ public: * @param depth_attachment 深度附件(可选) */ void begin_rendering( - VkExtent2D extent, + vk::Extent2D extent, std::span color_attachments, const depth_attachment_info* depth_attachment = nullptr); @@ -347,7 +350,7 @@ public: * @param bind_point 绑定点 * @param pipeline 管线句柄 */ - void bind_pipeline(VkPipelineBindPoint bind_point, VkPipeline pipeline); + void bind_pipeline(vk::PipelineBindPoint bind_point, vk::Pipeline pipeline); /** * @brief 绑定顶点缓冲 @@ -356,8 +359,8 @@ public: * @param offsets 偏移量列表 */ void bind_vertex_buffers(u32 first_binding, - std::span buffers, - std::span offsets); + std::span buffers, + std::span offsets); /** * @brief 绑定单个顶点缓冲 @@ -365,7 +368,7 @@ public: * @param buffer 缓冲句柄 * @param offset 偏移量 */ - void bind_vertex_buffer(u32 binding, VkBuffer buffer, VkDeviceSize offset = 0); + void bind_vertex_buffer(u32 binding, vk::Buffer buffer, vk::DeviceSize offset = 0); /** * @brief 绑定索引缓冲 @@ -373,7 +376,7 @@ public: * @param offset 偏移量 * @param index_type 索引类型 */ - void bind_index_buffer(VkBuffer buffer, VkDeviceSize offset, VkIndexType index_type); + void bind_index_buffer(vk::Buffer buffer, vk::DeviceSize offset, vk::IndexType index_type); /** * @brief 绑定描述符集 @@ -383,10 +386,10 @@ public: * @param descriptor_sets 描述符集列表 * @param dynamic_offsets 动态偏移量列表 */ - void bind_descriptor_sets(VkPipelineBindPoint bind_point, - VkPipelineLayout layout, + void bind_descriptor_sets(vk::PipelineBindPoint bind_point, + vk::PipelineLayout layout, u32 first_set, - std::span descriptor_sets, + std::span descriptor_sets, std::span dynamic_offsets = {}); // ============================================================================================ @@ -421,7 +424,7 @@ public: * @param draw_count 绘制数量 * @param stride 步幅 */ - void draw_indirect(VkBuffer buffer, VkDeviceSize offset, u32 draw_count, u32 stride); + void draw_indirect(vk::Buffer buffer, vk::DeviceSize offset, u32 draw_count, u32 stride); /** * @brief 间接索引绘制 @@ -430,7 +433,7 @@ public: * @param draw_count 绘制数量 * @param stride 步幅 */ - void draw_indexed_indirect(VkBuffer buffer, VkDeviceSize offset, u32 draw_count, u32 stride); + void draw_indexed_indirect(vk::Buffer buffer, vk::DeviceSize offset, u32 draw_count, u32 stride); // ============================================================================================ // 计算命令 @@ -449,7 +452,7 @@ public: * @param buffer 间接缓冲 * @param offset 偏移量 */ - void dispatch_indirect(VkBuffer buffer, VkDeviceSize offset); + void dispatch_indirect(vk::Buffer buffer, vk::DeviceSize offset); // ============================================================================================ // 同步命令(Synchronization2) @@ -459,7 +462,7 @@ public: * @brief 管线屏障(Synchronization2) * @param dependency_info 依赖信息 */ - void pipeline_barrier(const VkDependencyInfo& dependency_info); + void pipeline_barrier(const vk::DependencyInfo& dependency_info); /** * @brief 内存屏障 @@ -480,10 +483,10 @@ public: * @param new_layout 新布局 * @param subresource_range 子资源范围 */ - void transition_image_layout(VkImage image, - VkImageLayout old_layout, - VkImageLayout new_layout, - const VkImageSubresourceRange& subresource_range); + void transition_image_layout(vk::Image image, + vk::ImageLayout old_layout, + vk::ImageLayout new_layout, + const vk::ImageSubresourceRange& subresource_range); /** * @brief 缓冲内存屏障 @@ -501,7 +504,7 @@ public: * @param dst 目标缓冲 * @param regions 复制区域 */ - void copy_buffer(VkBuffer src, VkBuffer dst, std::span regions); + void copy_buffer(vk::Buffer src, vk::Buffer dst, std::span regions); /** * @brief 复制缓冲(简化版本) @@ -511,8 +514,8 @@ public: * @param src_offset 源偏移 * @param dst_offset 目标偏移 */ - void copy_buffer(VkBuffer src, VkBuffer dst, VkDeviceSize size, - VkDeviceSize src_offset = 0, VkDeviceSize dst_offset = 0); + void copy_buffer(vk::Buffer src, vk::Buffer dst, vk::DeviceSize size, + vk::DeviceSize src_offset = 0, vk::DeviceSize dst_offset = 0); /** * @brief 复制图像 @@ -522,9 +525,9 @@ public: * @param dst_layout 目标布局 * @param regions 复制区域 */ - void copy_image(VkImage src, VkImageLayout src_layout, - VkImage dst, VkImageLayout dst_layout, - std::span regions); + void copy_image(vk::Image src, vk::ImageLayout src_layout, + vk::Image dst, vk::ImageLayout dst_layout, + std::span regions); /** * @brief 复制缓冲到图像 @@ -533,8 +536,8 @@ public: * @param dst_layout 目标布局 * @param regions 复制区域 */ - void copy_buffer_to_image(VkBuffer src, VkImage dst, VkImageLayout dst_layout, - std::span regions); + void copy_buffer_to_image(vk::Buffer src, vk::Image dst, vk::ImageLayout dst_layout, + std::span regions); /** * @brief 复制图像到缓冲 @@ -543,8 +546,8 @@ public: * @param dst 目标缓冲 * @param regions 复制区域 */ - void copy_image_to_buffer(VkImage src, VkImageLayout src_layout, VkBuffer dst, - std::span regions); + void copy_image_to_buffer(vk::Image src, vk::ImageLayout src_layout, vk::Buffer dst, + std::span regions); // ============================================================================================ // 推送常量 @@ -558,7 +561,7 @@ public: * @param size 大小 * @param data 数据指针 */ - void push_constants(VkPipelineLayout layout, VkShaderStageFlags stage_flags, + void push_constants(vk::PipelineLayout layout, vk::ShaderStageFlags stage_flags, u32 offset, u32 size, const void* data); /** @@ -570,7 +573,7 @@ public: * @param offset 偏移量 */ template - void push_constants(VkPipelineLayout layout, VkShaderStageFlags stage_flags, + void push_constants(vk::PipelineLayout layout, vk::ShaderStageFlags stage_flags, const T& data, u32 offset = 0) { push_constants(layout, stage_flags, offset, sizeof(T), &data); } @@ -584,7 +587,7 @@ public: * @param first_viewport 第一个视口索引 * @param viewports 视口列表 */ - void set_viewport(u32 first_viewport, std::span viewports); + void set_viewport(u32 first_viewport, std::span viewports); /** * @brief 设置视口(简化版本) @@ -603,7 +606,7 @@ public: * @param first_scissor 第一个裁剪矩形索引 * @param scissors 裁剪矩形列表 */ - void set_scissor(u32 first_scissor, std::span scissors); + void set_scissor(u32 first_scissor, std::span scissors); /** * @brief 设置裁剪矩形(简化版本) @@ -625,9 +628,9 @@ public: * @param clear_color 清除颜色 * @param ranges 子资源范围 */ - void clear_color_image(VkImage image, VkImageLayout layout, - const VkClearColorValue& clear_color, - std::span ranges); + void clear_color_image(vk::Image image, vk::ImageLayout layout, + const vk::ClearColorValue& clear_color, + std::span ranges); /** * @brief 清除深度模板图像 @@ -636,9 +639,9 @@ public: * @param clear_value 清除值 * @param ranges 子资源范围 */ - void clear_depth_stencil_image(VkImage image, VkImageLayout layout, - const VkClearDepthStencilValue& clear_value, - std::span ranges); + void clear_depth_stencil_image(vk::Image image, vk::ImageLayout layout, + const vk::ClearDepthStencilValue& clear_value, + std::span ranges); /** * @brief 填充缓冲 @@ -647,13 +650,13 @@ public: * @param size 大小 * @param data 填充数据 */ - void fill_buffer(VkBuffer buffer, VkDeviceSize offset, VkDeviceSize size, u32 data); + void fill_buffer(vk::Buffer buffer, vk::DeviceSize offset, vk::DeviceSize size, u32 data); /** * @brief 执行二级命令缓冲 * @param command_buffers 二级命令缓冲列表 */ - void execute_commands(std::span command_buffers); + void execute_commands(std::span command_buffers); // ============================================================================================ // 属性访问 @@ -661,9 +664,9 @@ public: /** * @brief 获取命令缓冲句柄 - * @return VkCommandBuffer 句柄 + * @return vk::CommandBuffer 句柄 */ - [[nodiscard]] VkCommandBuffer get_vulkan_buffer() const noexcept { + [[nodiscard]] vk::CommandBuffer get_vulkan_buffer() const noexcept { return buffer_; } @@ -672,13 +675,13 @@ public: * @return 如果有效返回 true */ [[nodiscard]] bool is_valid() const noexcept { - return buffer_ != VK_NULL_HANDLE; + return !!buffer_; } /** - * @brief 隐式转换为 VkCommandBuffer + * @brief 隐式转换为 vk::CommandBuffer */ - operator VkCommandBuffer() const noexcept { + operator vk::CommandBuffer() const noexcept { return buffer_; } @@ -686,7 +689,7 @@ public: * @brief 获取命令缓冲级别 * @return 命令缓冲级别 */ - [[nodiscard]] VkCommandBufferLevel get_level() const noexcept { + [[nodiscard]] vk::CommandBufferLevel get_level() const noexcept { return level_; } @@ -710,10 +713,10 @@ private: command_pool* pool_ = nullptr; /// 命令缓冲句柄 - VkCommandBuffer buffer_ = VK_NULL_HANDLE; + vk::CommandBuffer buffer_; /// 命令缓冲级别 - VkCommandBufferLevel level_ = VK_COMMAND_BUFFER_LEVEL_PRIMARY; + vk::CommandBufferLevel level_ = vk::CommandBufferLevel::ePrimary; /// 是否正在录制 bool recording_ = false; diff --git a/src/render/frame_sync.cpp b/src/render/frame_sync.cpp index c433646..2c46beb 100644 --- a/src/render/frame_sync.cpp +++ b/src/render/frame_sync.cpp @@ -32,21 +32,21 @@ frame_sync::frame_sync(std::shared_ptr device, // 创建同步对象和命令缓冲 if (!create_sync_objects()) { - LOG_ERROR("Failed to create sync objects"); + MILAI_LOG_ERROR("Failed to create sync objects"); return; } if (!create_command_buffers()) { - LOG_ERROR("Failed to create command buffers"); + MILAI_LOG_ERROR("Failed to create command buffers"); destroy_sync_objects(); return; } // 初始化图像飞行中栅栏 u32 image_count = swapchain_ ? swapchain_->get_image_count() : 0; - images_in_flight_.resize(image_count, VK_NULL_HANDLE); + images_in_flight_.resize(image_count, nullptr); - LOG_DEBUG("Frame sync created with {} frames in flight", frames_in_flight_); + MILAI_LOG_DEBUG("Frame sync created with {} frames in flight", frames_in_flight_); } frame_sync::~frame_sync() { @@ -73,7 +73,7 @@ frame_sync::frame_sync(frame_sync&& other) noexcept , on_frame_begin_(std::move(other.on_frame_begin_)) , on_frame_end_(std::move(other.on_frame_end_)) { - other.command_pool_ = VK_NULL_HANDLE; + other.command_pool_ = nullptr; other.frames_in_flight_ = 0; other.current_frame_ = 0; other.current_image_index_ = 0; @@ -102,7 +102,7 @@ frame_sync& frame_sync::operator=(frame_sync&& other) noexcept { on_frame_end_ = std::move(other.on_frame_end_); // 清空源对象 - other.command_pool_ = VK_NULL_HANDLE; + other.command_pool_ = nullptr; other.frames_in_flight_ = 0; other.current_frame_ = 0; other.current_image_index_ = 0; @@ -118,18 +118,16 @@ std::pair frame_sync::begin_frame() { const auto& resources = frame_resources_[current_frame_]; // 等待当前帧的栅栏 - VkResult result = vkWaitForFences(device_->get_device(), 1, - &resources.in_flight_fence, - VK_TRUE, fence_timeout_); + vk::Result result = device_->get_device().waitForFences(resources.in_flight_fence, vk::True, fence_timeout_); - if (result == VK_TIMEOUT) { - LOG_WARN("Frame fence wait timed out"); + if (result == vk::Result::eTimeout) { + MILAI_LOG_WARN("Frame fence wait timed out"); return {frame_begin_result::timeout, 0}; - } else if (result == VK_ERROR_DEVICE_LOST) { - LOG_ERROR("Device lost while waiting for frame fence"); + } else if (result == vk::Result::eErrorDeviceLost) { + MILAI_LOG_ERROR("Device lost while waiting for frame fence"); return {frame_begin_result::device_lost, 0}; - } else if (result != VK_SUCCESS) { - LOG_ERROR("Failed to wait for frame fence: {}", vk_result_to_string(result)); + } else if (result != vk::Result::eSuccess) { + MILAI_LOG_ERROR("Failed to wait for frame fence: {}", vk::to_string(result)); return {frame_begin_result::error, 0}; } @@ -141,24 +139,22 @@ std::pair frame_sync::begin_frame() { return {frame_begin_result::swapchain_out_of_date, 0}; } else if (acquire_result != acquire_result::success && acquire_result != acquire_result::suboptimal) { - LOG_ERROR("Failed to acquire swapchain image"); + MILAI_LOG_ERROR("Failed to acquire swapchain image"); return {frame_begin_result::error, 0}; } current_image_index_ = image_index; // 检查图像是否仍在使用中 - if (images_in_flight_[image_index] != VK_NULL_HANDLE) { - vkWaitForFences(device_->get_device(), 1, - &images_in_flight_[image_index], - VK_TRUE, fence_timeout_); + if (images_in_flight_[image_index]) { + device_->get_device().waitForFences(images_in_flight_[image_index], vk::True, fence_timeout_); } // 标记该图像为当前帧正在使用 images_in_flight_[image_index] = resources.in_flight_fence; // 重置栅栏 - vkResetFences(device_->get_device(), 1, &resources.in_flight_fence); + device_->get_device().resetFences(resources.in_flight_fence); // 调用帧开始回调 if (on_frame_begin_) { @@ -168,7 +164,7 @@ std::pair frame_sync::begin_frame() { return {frame_begin_result::success, current_image_index_}; } -frame_end_result frame_sync::end_frame(VkCommandBuffer cmd_buffer) { +frame_end_result frame_sync::end_frame(vk::CommandBuffer cmd_buffer) { if (!is_valid() || !swapchain_) { return frame_end_result::error; } @@ -176,33 +172,26 @@ frame_end_result frame_sync::end_frame(VkCommandBuffer cmd_buffer) { const auto& resources = frame_resources_[current_frame_]; // 提交命令缓冲 - VkSubmitInfo submit_info{}; - submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; + vk::SubmitInfo submit_info{}; - VkSemaphore wait_semaphores[] = {resources.image_available_semaphore}; - VkPipelineStageFlags wait_stages[] = {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT}; - submit_info.waitSemaphoreCount = 1; - submit_info.pWaitSemaphores = wait_semaphores; - submit_info.pWaitDstStageMask = wait_stages; - submit_info.commandBufferCount = 1; - submit_info.pCommandBuffers = &cmd_buffer; + vk::Semaphore wait_semaphores[] = {resources.image_available_semaphore}; + vk::PipelineStageFlags wait_stages[] = {vk::PipelineStageFlagBits::eColorAttachmentOutput}; + submit_info.setWaitSemaphores(wait_semaphores) + .setWaitDstStageMask(wait_stages) + .setCommandBuffers(cmd_buffer); - VkSemaphore signal_semaphores[] = {resources.render_finished_semaphore}; - submit_info.signalSemaphoreCount = 1; - submit_info.pSignalSemaphores = signal_semaphores; + vk::Semaphore signal_semaphores[] = {resources.render_finished_semaphore}; + submit_info.setSignalSemaphores(signal_semaphores); - VkResult result = vkQueueSubmit(device_->get_graphics_queue(), 1, - &submit_info, resources.in_flight_fence); - - if (result != VK_SUCCESS) { - LOG_ERROR("Failed to submit command buffer: {}", vk_result_to_string(result)); + vk::Result submit_result = device_->get_graphics_queue().submit(submit_info, resources.in_flight_fence); + if (submit_result != vk::Result::eSuccess) { + MILAI_LOG_ERROR("Failed to submit command buffer: {}", vk::to_string(submit_result)); return frame_end_result::error; } // 呈现图像 - VkSemaphore present_wait_semaphores[] = {resources.render_finished_semaphore}; - auto present_result = swapchain_->present(device_->get_present_queue(), - {present_wait_semaphores, 1}); + auto present_result = swapchain_->present(current_image_index_, + resources.render_finished_semaphore); // 调用帧结束回调 if (on_frame_end_) { @@ -234,12 +223,11 @@ bool frame_sync::wait_for_current_frame() { } const auto& resources = frame_resources_[current_frame_]; - VkResult result = vkWaitForFences(device_->get_device(), 1, - &resources.in_flight_fence, - VK_TRUE, fence_timeout_); + vk::Result result = device_->get_device().waitForFences(resources.in_flight_fence, + vk::True, fence_timeout_); - if (result != VK_SUCCESS) { - LOG_ERROR("Failed to wait for current frame: {}", vk_result_to_string(result)); + if (result != vk::Result::eSuccess) { + MILAI_LOG_ERROR("Failed to wait for current frame: {}", vk::to_string(result)); return false; } @@ -252,10 +240,10 @@ bool frame_sync::wait_for_all_frames() { } // 收集所有栅栏 - std::vector fences; + std::vector fences; fences.reserve(frames_in_flight_); for (const auto& resources : frame_resources_) { - if (resources.in_flight_fence != VK_NULL_HANDLE) { + if (resources.in_flight_fence) { fences.push_back(resources.in_flight_fence); } } @@ -264,12 +252,10 @@ bool frame_sync::wait_for_all_frames() { return true; } - VkResult result = vkWaitForFences(device_->get_device(), - static_cast(fences.size()), - fences.data(), VK_TRUE, fence_timeout_); + vk::Result result = device_->get_device().waitForFences(fences, vk::True, fence_timeout_); - if (result != VK_SUCCESS) { - LOG_ERROR("Failed to wait for all frames: {}", vk_result_to_string(result)); + if (result != vk::Result::eSuccess) { + MILAI_LOG_ERROR("Failed to wait for all frames: {}", vk::to_string(result)); return false; } @@ -290,22 +276,22 @@ bool frame_sync::recreate(std::shared_ptr new_swapchain) { // 重新初始化图像飞行中栅栏 u32 image_count = swapchain_ ? swapchain_->get_image_count() : 0; images_in_flight_.clear(); - images_in_flight_.resize(image_count, VK_NULL_HANDLE); + images_in_flight_.resize(image_count, nullptr); // 重置当前帧索引 current_frame_ = 0; current_image_index_ = 0; - LOG_DEBUG("Frame sync recreated for new swapchain"); + MILAI_LOG_DEBUG("Frame sync recreated for new swapchain"); return true; } void frame_sync::on_created() { - LOG_DEBUG("Frame sync created"); + MILAI_LOG_DEBUG("Frame sync created"); } void frame_sync::on_destroying() { - LOG_DEBUG("Frame sync destroying"); + MILAI_LOG_DEBUG("Frame sync destroying"); } bool frame_sync::create_sync_objects() { @@ -315,45 +301,43 @@ bool frame_sync::create_sync_objects() { frame_resources_.resize(frames_in_flight_); - VkSemaphoreCreateInfo semaphore_info{}; - semaphore_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; + vk::SemaphoreCreateInfo semaphore_info{}; - VkFenceCreateInfo fence_info{}; - fence_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; - fence_info.flags = VK_FENCE_CREATE_SIGNALED_BIT; // 初始状态为已信号 + vk::FenceCreateInfo fence_info{}; + fence_info.flags = vk::FenceCreateFlagBits::eSignaled; // 初始状态为已信号 for (u32 i = 0; i < frames_in_flight_; ++i) { auto& resources = frame_resources_[i]; // 创建图像可用信号量 - VkResult result = vkCreateSemaphore(device_->get_device(), &semaphore_info, - nullptr, &resources.image_available_semaphore); - if (result != VK_SUCCESS) { - LOG_ERROR("Failed to create image available semaphore: {}", - vk_result_to_string(result)); + auto image_sem_result = device_->get_device().createSemaphore(semaphore_info); + if (image_sem_result.result != vk::Result::eSuccess) { + MILAI_LOG_ERROR("Failed to create image available semaphore: {}", + vk::to_string(image_sem_result.result)); return false; } + resources.image_available_semaphore = image_sem_result.value; // 创建渲染完成信号量 - result = vkCreateSemaphore(device_->get_device(), &semaphore_info, - nullptr, &resources.render_finished_semaphore); - if (result != VK_SUCCESS) { - LOG_ERROR("Failed to create render finished semaphore: {}", - vk_result_to_string(result)); + auto render_sem_result = device_->get_device().createSemaphore(semaphore_info); + if (render_sem_result.result != vk::Result::eSuccess) { + MILAI_LOG_ERROR("Failed to create render finished semaphore: {}", + vk::to_string(render_sem_result.result)); return false; } + resources.render_finished_semaphore = render_sem_result.value; // 创建飞行中栅栏 - result = vkCreateFence(device_->get_device(), &fence_info, - nullptr, &resources.in_flight_fence); - if (result != VK_SUCCESS) { - LOG_ERROR("Failed to create in flight fence: {}", - vk_result_to_string(result)); + auto fence_result = device_->get_device().createFence(fence_info); + if (fence_result.result != vk::Result::eSuccess) { + MILAI_LOG_ERROR("Failed to create in flight fence: {}", + vk::to_string(fence_result.result)); return false; } + resources.in_flight_fence = fence_result.value; } - LOG_DEBUG("Created {} sets of sync objects", frames_in_flight_); + MILAI_LOG_DEBUG("Created {} sets of sync objects", frames_in_flight_); return true; } @@ -363,38 +347,40 @@ bool frame_sync::create_command_buffers() { } // 创建命令池 - VkCommandPoolCreateInfo pool_info{}; - pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; - pool_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; - pool_info.queueFamilyIndex = device_->get_queue_family_indices().graphics_family; - - VkResult result = vkCreateCommandPool(device_->get_device(), &pool_info, - nullptr, &command_pool_); - if (result != VK_SUCCESS) { - LOG_ERROR("Failed to create command pool: {}", vk_result_to_string(result)); + vk::CommandPoolCreateInfo pool_info{}; + pool_info.flags = vk::CommandPoolCreateFlagBits::eResetCommandBuffer; + if (device_->get_queue_family_indices().graphics_family.has_value()) { + pool_info.queueFamilyIndex = device_->get_queue_family_indices().graphics_family.value(); + } else { + MILAI_LOG_ERROR("No graphics queue family found"); return false; } + auto pool_result = device_->get_device().createCommandPool(pool_info); + if (pool_result.result != vk::Result::eSuccess) { + MILAI_LOG_ERROR("Failed to create command pool: {}", vk::to_string(pool_result.result)); + return false; + } + command_pool_ = pool_result.value; + // 分配命令缓冲 - std::vector buffers(frames_in_flight_); - - VkCommandBufferAllocateInfo alloc_info{}; - alloc_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; + vk::CommandBufferAllocateInfo alloc_info{}; alloc_info.commandPool = command_pool_; - alloc_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; + alloc_info.level = vk::CommandBufferLevel::ePrimary; alloc_info.commandBufferCount = frames_in_flight_; - result = vkAllocateCommandBuffers(device_->get_device(), &alloc_info, buffers.data()); - if (result != VK_SUCCESS) { - LOG_ERROR("Failed to allocate command buffers: {}", vk_result_to_string(result)); + auto alloc_result = device_->get_device().allocateCommandBuffers(alloc_info); + if (alloc_result.result != vk::Result::eSuccess) { + MILAI_LOG_ERROR("Failed to allocate command buffers: {}", vk::to_string(alloc_result.result)); return false; } + auto buffers = alloc_result.value; for (u32 i = 0; i < frames_in_flight_; ++i) { frame_resources_[i].command_buffer = buffers[i]; } - LOG_DEBUG("Created command pool and {} command buffers", frames_in_flight_); + MILAI_LOG_DEBUG("Created command pool and {} command buffers", frames_in_flight_); return true; } @@ -404,20 +390,17 @@ void frame_sync::destroy_sync_objects() { } for (auto& resources : frame_resources_) { - if (resources.image_available_semaphore != VK_NULL_HANDLE) { - vkDestroySemaphore(device_->get_device(), - resources.image_available_semaphore, nullptr); - resources.image_available_semaphore = VK_NULL_HANDLE; + if (resources.image_available_semaphore) { + device_->get_device().destroySemaphore(resources.image_available_semaphore); + resources.image_available_semaphore = nullptr; } - if (resources.render_finished_semaphore != VK_NULL_HANDLE) { - vkDestroySemaphore(device_->get_device(), - resources.render_finished_semaphore, nullptr); - resources.render_finished_semaphore = VK_NULL_HANDLE; + if (resources.render_finished_semaphore) { + device_->get_device().destroySemaphore(resources.render_finished_semaphore); + resources.render_finished_semaphore = nullptr; } - if (resources.in_flight_fence != VK_NULL_HANDLE) { - vkDestroyFence(device_->get_device(), - resources.in_flight_fence, nullptr); - resources.in_flight_fence = VK_NULL_HANDLE; + if (resources.in_flight_fence) { + device_->get_device().destroyFence(resources.in_flight_fence); + resources.in_flight_fence = nullptr; } } } @@ -428,13 +411,13 @@ void frame_sync::destroy_command_buffers() { } // 命令缓冲在命令池销毁时自动释放 - if (command_pool_ != VK_NULL_HANDLE) { - vkDestroyCommandPool(device_->get_device(), command_pool_, nullptr); - command_pool_ = VK_NULL_HANDLE; + if (command_pool_) { + device_->get_device().destroyCommandPool(command_pool_); + command_pool_ = nullptr; } for (auto& resources : frame_resources_) { - resources.command_buffer = VK_NULL_HANDLE; + resources.command_buffer = nullptr; } } diff --git a/src/render/frame_sync.hpp b/src/render/frame_sync.hpp index 9a45f3a..560b8f0 100644 --- a/src/render/frame_sync.hpp +++ b/src/render/frame_sync.hpp @@ -16,10 +16,12 @@ #include "object.hpp" #include "types.hpp" -#include +#define VULKAN_HPP_NO_EXCEPTIONS +#include #include #include #include +#include namespace milai { @@ -44,16 +46,16 @@ struct frame_sync_config { */ struct frame_resources { /// 图像可用信号量 - VkSemaphore image_available_semaphore = VK_NULL_HANDLE; + vk::Semaphore image_available_semaphore; /// 渲染完成信号量 - VkSemaphore render_finished_semaphore = VK_NULL_HANDLE; + vk::Semaphore render_finished_semaphore; /// 飞行中栅栏 - VkFence in_flight_fence = VK_NULL_HANDLE; + vk::Fence in_flight_fence; /// 命令缓冲 - VkCommandBuffer command_buffer = VK_NULL_HANDLE; + vk::CommandBuffer command_buffer; }; /** @@ -132,13 +134,13 @@ public: /** * @brief 结束帧 - * + * * 提交命令缓冲并呈现图像。 - * + * * @param cmd_buffer 要提交的命令缓冲 * @return 帧结束结果 */ - [[nodiscard]] frame_end_result end_frame(VkCommandBuffer cmd_buffer); + [[nodiscard]] frame_end_result end_frame(vk::CommandBuffer cmd_buffer); /** * @brief 结束帧(使用当前帧的命令缓冲) @@ -198,7 +200,7 @@ public: * @brief 获取图像可用信号量 * @return 当前帧的图像可用信号量 */ - [[nodiscard]] VkSemaphore get_image_available_semaphore() const { + [[nodiscard]] vk::Semaphore get_image_available_semaphore() const { return frame_resources_[current_frame_].image_available_semaphore; } @@ -206,7 +208,7 @@ public: * @brief 获取渲染完成信号量 * @return 当前帧的渲染完成信号量 */ - [[nodiscard]] VkSemaphore get_render_finished_semaphore() const { + [[nodiscard]] vk::Semaphore get_render_finished_semaphore() const { return frame_resources_[current_frame_].render_finished_semaphore; } @@ -214,7 +216,7 @@ public: * @brief 获取飞行中栅栏 * @return 当前帧的飞行中栅栏 */ - [[nodiscard]] VkFence get_in_flight_fence() const { + [[nodiscard]] vk::Fence get_in_flight_fence() const { return frame_resources_[current_frame_].in_flight_fence; } @@ -222,7 +224,7 @@ public: * @brief 获取当前帧的命令缓冲 * @return 当前帧的命令缓冲 */ - [[nodiscard]] VkCommandBuffer get_current_command_buffer() const { + [[nodiscard]] vk::CommandBuffer get_current_command_buffer() const { return frame_resources_[current_frame_].command_buffer; } @@ -311,13 +313,13 @@ private: std::shared_ptr swapchain_; /// 命令池 - VkCommandPool command_pool_ = VK_NULL_HANDLE; + vk::CommandPool command_pool_; /// 帧资源列表 std::vector frame_resources_; /// 图像飞行中栅栏(用于跟踪每个交换链图像的使用状态) - std::vector images_in_flight_; + std::vector images_in_flight_; /// 飞行中帧数 u32 frames_in_flight_ = 2; @@ -418,7 +420,7 @@ private: bool samples_filled_ = false; /// 帧开始时间 - std::chrono::high_resolution_clock::time_point frame_start_time_; + std::chrono::time_point frame_start_time_; /// 当前帧时间(毫秒) f64 current_frame_time_ms_ = 0.0; diff --git a/src/render/pipeline.cpp b/src/render/pipeline.cpp index 3ea27a7..b7b2dc8 100644 --- a/src/render/pipeline.cpp +++ b/src/render/pipeline.cpp @@ -14,27 +14,25 @@ namespace milai { // pipeline_layout 实现 // ================================================================================================ -pipeline_layout::pipeline_layout(std::shared_ptr device, +pipeline_layout::pipeline_layout(std::shared_ptr device, const pipeline_layout_config& config) : device_(std::move(device)) { - VkPipelineLayoutCreateInfo create_info{}; - create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; - create_info.setLayoutCount = static_cast(config.descriptor_set_layouts.size()); - create_info.pSetLayouts = config.descriptor_set_layouts.data(); - create_info.pushConstantRangeCount = static_cast(config.push_constant_ranges.size()); - create_info.pPushConstantRanges = config.push_constant_ranges.data(); + vk::PipelineLayoutCreateInfo create_info{}; + create_info.setSetLayouts(config.descriptor_set_layouts) + .setPushConstantRanges(config.push_constant_ranges); - VkResult result = vkCreatePipelineLayout(device_->get_device(), &create_info, nullptr, &layout_); - if (result != VK_SUCCESS) { - LOG_ERROR("Failed to create pipeline layout: {}", vk_result_to_string(result)); + auto [result, layout] = device_->get_device().createPipelineLayout(create_info); + if (result != vk::Result::eSuccess) { + MILAI_LOG_ERROR("Failed to create pipeline layout: {}", vk::to_string(result)); } + layout_ = layout; } pipeline_layout::~pipeline_layout() { - if (layout_ != VK_NULL_HANDLE && device_ && device_->is_valid()) { - vkDestroyPipelineLayout(device_->get_device(), layout_, nullptr); - layout_ = VK_NULL_HANDLE; + if (layout_ && device_ && device_->is_valid()) { + device_->get_device().destroyPipelineLayout(layout_); + layout_ = nullptr; } } @@ -42,28 +40,28 @@ pipeline_layout::pipeline_layout(pipeline_layout&& other) noexcept : device_(std::move(other.device_)) , layout_(other.layout_) { - other.layout_ = VK_NULL_HANDLE; + other.layout_ = nullptr; } pipeline_layout& pipeline_layout::operator=(pipeline_layout&& other) noexcept { if (this != &other) { - if (layout_ != VK_NULL_HANDLE && device_ && device_->is_valid()) { - vkDestroyPipelineLayout(device_->get_device(), layout_, nullptr); + if (layout_ && device_ && device_->is_valid()) { + device_->get_device().destroyPipelineLayout(layout_); } device_ = std::move(other.device_); layout_ = other.layout_; - other.layout_ = VK_NULL_HANDLE; + other.layout_ = nullptr; } return *this; } void pipeline_layout::on_created() { - LOG_DEBUG("Pipeline layout created"); + MILAI_LOG_DEBUG("Pipeline layout created"); } void pipeline_layout::on_destroying() { - LOG_DEBUG("Pipeline layout destroying"); + MILAI_LOG_DEBUG("Pipeline layout destroying"); } // ================================================================================================ @@ -75,74 +73,73 @@ graphics_pipeline_builder::graphics_pipeline_builder(std::shared_ptr bindings) { vertex_bindings_.clear(); - for (const auto& binding : bindings) { - add_vertex_binding(binding.binding, binding.stride, binding.input_rate); + for (const auto& b : bindings) { + add_vertex_binding(b.binding, b.stride, b.input_rate); } return *this; } @@ -168,7 +165,7 @@ graphics_pipeline_builder& graphics_pipeline_builder::set_vertex_attributes( return *this; } -graphics_pipeline_builder& graphics_pipeline_builder::set_topology(VkPrimitiveTopology topology) { +graphics_pipeline_builder& graphics_pipeline_builder::set_topology(vk::PrimitiveTopology topology) { topology_ = topology; return *this; } @@ -178,17 +175,17 @@ graphics_pipeline_builder& graphics_pipeline_builder::set_primitive_restart(bool return *this; } -graphics_pipeline_builder& graphics_pipeline_builder::set_polygon_mode(VkPolygonMode mode) { +graphics_pipeline_builder& graphics_pipeline_builder::set_polygon_mode(vk::PolygonMode mode) { polygon_mode_ = mode; return *this; } -graphics_pipeline_builder& graphics_pipeline_builder::set_cull_mode(VkCullModeFlags cull_mode) { +graphics_pipeline_builder& graphics_pipeline_builder::set_cull_mode(vk::CullModeFlags cull_mode) { cull_mode_ = cull_mode; return *this; } -graphics_pipeline_builder& graphics_pipeline_builder::set_front_face(VkFrontFace front_face) { +graphics_pipeline_builder& graphics_pipeline_builder::set_front_face(vk::FrontFace front_face) { front_face_ = front_face; return *this; } @@ -218,7 +215,7 @@ graphics_pipeline_builder& graphics_pipeline_builder::set_depth_bias( return *this; } -graphics_pipeline_builder& graphics_pipeline_builder::set_samples(VkSampleCountFlagBits samples) { +graphics_pipeline_builder& graphics_pipeline_builder::set_samples(vk::SampleCountFlagBits samples) { samples_ = samples; return *this; } @@ -242,7 +239,7 @@ graphics_pipeline_builder& graphics_pipeline_builder::enable_alpha_to_one(bool e } graphics_pipeline_builder& graphics_pipeline_builder::enable_depth_test( - bool enable, VkCompareOp compare_op) + bool enable, vk::CompareOp compare_op) { depth_test_enable_ = enable; depth_compare_op_ = compare_op; @@ -269,7 +266,7 @@ graphics_pipeline_builder& graphics_pipeline_builder::enable_stencil_test(bool e } graphics_pipeline_builder& graphics_pipeline_builder::set_stencil_op( - const VkStencilOpState& front, const VkStencilOpState& back) + const vk::StencilOpState& front, const vk::StencilOpState& back) { stencil_front_ = front; stencil_back_ = back; @@ -278,68 +275,68 @@ graphics_pipeline_builder& graphics_pipeline_builder::set_stencil_op( graphics_pipeline_builder& graphics_pipeline_builder::enable_blending(bool enable) { if (color_blend_attachments_.empty()) { - VkPipelineColorBlendAttachmentState attachment{}; - attachment.blendEnable = enable ? VK_TRUE : VK_FALSE; - attachment.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA; - attachment.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; - attachment.colorBlendOp = VK_BLEND_OP_ADD; - attachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE; - attachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; - attachment.alphaBlendOp = VK_BLEND_OP_ADD; - attachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | - VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; + vk::PipelineColorBlendAttachmentState attachment{}; + attachment.setBlendEnable(enable) + .setSrcColorBlendFactor(vk::BlendFactor::eSrcAlpha) + .setDstColorBlendFactor(vk::BlendFactor::eOneMinusSrcAlpha) + .setColorBlendOp(vk::BlendOp::eAdd) + .setSrcAlphaBlendFactor(vk::BlendFactor::eOne) + .setDstAlphaBlendFactor(vk::BlendFactor::eOneMinusSrcAlpha) + .setAlphaBlendOp(vk::BlendOp::eAdd) + .setColorWriteMask(vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG | + vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eA); color_blend_attachments_.push_back(attachment); } else { for (auto& attachment : color_blend_attachments_) { - attachment.blendEnable = enable ? VK_TRUE : VK_FALSE; + attachment.setBlendEnable(enable); } } return *this; } graphics_pipeline_builder& graphics_pipeline_builder::set_blend_factors( - VkBlendFactor src_color, VkBlendFactor dst_color, - VkBlendFactor src_alpha, VkBlendFactor dst_alpha) + vk::BlendFactor src_color, vk::BlendFactor dst_color, + vk::BlendFactor src_alpha, vk::BlendFactor dst_alpha) { if (color_blend_attachments_.empty()) { enable_blending(true); } for (auto& attachment : color_blend_attachments_) { - attachment.srcColorBlendFactor = src_color; - attachment.dstColorBlendFactor = dst_color; - attachment.srcAlphaBlendFactor = src_alpha; - attachment.dstAlphaBlendFactor = dst_alpha; + attachment.setSrcColorBlendFactor(src_color) + .setDstColorBlendFactor(dst_color) + .setSrcAlphaBlendFactor(src_alpha) + .setDstAlphaBlendFactor(dst_alpha); } return *this; } graphics_pipeline_builder& graphics_pipeline_builder::set_blend_op( - VkBlendOp color_op, VkBlendOp alpha_op) + vk::BlendOp color_op, vk::BlendOp alpha_op) { if (color_blend_attachments_.empty()) { enable_blending(true); } for (auto& attachment : color_blend_attachments_) { - attachment.colorBlendOp = color_op; - attachment.alphaBlendOp = alpha_op; + attachment.setColorBlendOp(color_op) + .setAlphaBlendOp(alpha_op); } return *this; } graphics_pipeline_builder& graphics_pipeline_builder::set_color_write_mask( - VkColorComponentFlags mask) + vk::ColorComponentFlags mask) { if (color_blend_attachments_.empty()) { enable_blending(false); } for (auto& attachment : color_blend_attachments_) { - attachment.colorWriteMask = mask; + attachment.setColorWriteMask(mask); } return *this; } graphics_pipeline_builder& graphics_pipeline_builder::add_color_blend_attachment( - const VkPipelineColorBlendAttachmentState& attachment) + const vk::PipelineColorBlendAttachmentState& attachment) { color_blend_attachments_.push_back(attachment); return *this; @@ -352,49 +349,49 @@ graphics_pipeline_builder& graphics_pipeline_builder::set_blend_constants( return *this; } -graphics_pipeline_builder& graphics_pipeline_builder::add_dynamic_state(VkDynamicState state) { +graphics_pipeline_builder& graphics_pipeline_builder::add_dynamic_state(vk::DynamicState state) { dynamic_states_.push_back(state); return *this; } graphics_pipeline_builder& graphics_pipeline_builder::set_dynamic_states( - std::span states) + std::span states) { dynamic_states_.clear(); dynamic_states_.assign(states.begin(), states.end()); return *this; } -graphics_pipeline_builder& graphics_pipeline_builder::set_color_format(VkFormat format) { +graphics_pipeline_builder& graphics_pipeline_builder::set_color_format(vk::Format format) { color_formats_.clear(); color_formats_.push_back(format); return *this; } -graphics_pipeline_builder& graphics_pipeline_builder::add_color_format(VkFormat format) { +graphics_pipeline_builder& graphics_pipeline_builder::add_color_format(vk::Format format) { color_formats_.push_back(format); return *this; } graphics_pipeline_builder& graphics_pipeline_builder::set_color_formats( - std::span formats) + std::span formats) { color_formats_.clear(); color_formats_.assign(formats.begin(), formats.end()); return *this; } -graphics_pipeline_builder& graphics_pipeline_builder::set_depth_format(VkFormat format) { +graphics_pipeline_builder& graphics_pipeline_builder::set_depth_format(vk::Format format) { depth_format_ = format; return *this; } -graphics_pipeline_builder& graphics_pipeline_builder::set_stencil_format(VkFormat format) { +graphics_pipeline_builder& graphics_pipeline_builder::set_stencil_format(vk::Format format) { stencil_format_ = format; return *this; } -graphics_pipeline_builder& graphics_pipeline_builder::set_layout(VkPipelineLayout layout) { +graphics_pipeline_builder& graphics_pipeline_builder::set_layout(vk::PipelineLayout layout) { layout_ = layout; return *this; } @@ -408,119 +405,98 @@ std::unique_ptr graphics_pipeline_builder::build() { // 确保有默认的颜色混合附件 if (color_blend_attachments_.empty() && !color_formats_.empty()) { for (size_t i = 0; i < color_formats_.size(); ++i) { - VkPipelineColorBlendAttachmentState attachment{}; - attachment.blendEnable = VK_FALSE; - attachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | - VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; + vk::PipelineColorBlendAttachmentState attachment{}; + attachment.setBlendEnable(false) + .setColorWriteMask(vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG | + vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eA); color_blend_attachments_.push_back(attachment); } } // 顶点输入状态 - VkPipelineVertexInputStateCreateInfo vertex_input_info{}; - vertex_input_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; - vertex_input_info.vertexBindingDescriptionCount = static_cast(vertex_bindings_.size()); - vertex_input_info.pVertexBindingDescriptions = vertex_bindings_.data(); - vertex_input_info.vertexAttributeDescriptionCount = static_cast(vertex_attributes_.size()); - vertex_input_info.pVertexAttributeDescriptions = vertex_attributes_.data(); + vk::PipelineVertexInputStateCreateInfo vertex_input_info{}; + vertex_input_info.setVertexBindingDescriptions(vertex_bindings_) + .setVertexAttributeDescriptions(vertex_attributes_); // 输入装配状态 - VkPipelineInputAssemblyStateCreateInfo input_assembly_info{}; - input_assembly_info.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; - input_assembly_info.topology = topology_; - input_assembly_info.primitiveRestartEnable = primitive_restart_enable_ ? VK_TRUE : VK_FALSE; + vk::PipelineInputAssemblyStateCreateInfo input_assembly_info{}; + input_assembly_info.setTopology(topology_) + .setPrimitiveRestartEnable(primitive_restart_enable_); // 视口状态(使用动态状态,所以这里只需要设置数量) - VkPipelineViewportStateCreateInfo viewport_info{}; - viewport_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; - viewport_info.viewportCount = 1; - viewport_info.scissorCount = 1; + vk::PipelineViewportStateCreateInfo viewport_info{}; + viewport_info.setViewportCount(1) + .setScissorCount(1); // 光栅化状态 - VkPipelineRasterizationStateCreateInfo rasterization_info{}; - rasterization_info.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; - rasterization_info.depthClampEnable = depth_clamp_enable_ ? VK_TRUE : VK_FALSE; - rasterization_info.rasterizerDiscardEnable = rasterizer_discard_enable_ ? VK_TRUE : VK_FALSE; - rasterization_info.polygonMode = polygon_mode_; - rasterization_info.cullMode = cull_mode_; - rasterization_info.frontFace = front_face_; - rasterization_info.depthBiasEnable = depth_bias_enable_ ? VK_TRUE : VK_FALSE; - rasterization_info.depthBiasConstantFactor = depth_bias_constant_factor_; - rasterization_info.depthBiasClamp = depth_bias_clamp_; - rasterization_info.depthBiasSlopeFactor = depth_bias_slope_factor_; - rasterization_info.lineWidth = line_width_; + vk::PipelineRasterizationStateCreateInfo rasterization_info{}; + rasterization_info.setDepthClampEnable(depth_clamp_enable_) + .setRasterizerDiscardEnable(rasterizer_discard_enable_) + .setPolygonMode(polygon_mode_) + .setCullMode(cull_mode_) + .setFrontFace(front_face_) + .setDepthBiasEnable(depth_bias_enable_) + .setDepthBiasConstantFactor(depth_bias_constant_factor_) + .setDepthBiasClamp(depth_bias_clamp_) + .setDepthBiasSlopeFactor(depth_bias_slope_factor_) + .setLineWidth(line_width_); // 多重采样状态 - VkPipelineMultisampleStateCreateInfo multisample_info{}; - multisample_info.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; - multisample_info.rasterizationSamples = samples_; - multisample_info.sampleShadingEnable = sample_shading_enable_ ? VK_TRUE : VK_FALSE; - multisample_info.minSampleShading = min_sample_shading_; - multisample_info.alphaToCoverageEnable = alpha_to_coverage_enable_ ? VK_TRUE : VK_FALSE; - multisample_info.alphaToOneEnable = alpha_to_one_enable_ ? VK_TRUE : VK_FALSE; + vk::PipelineMultisampleStateCreateInfo multisample_info{}; + multisample_info.setRasterizationSamples(samples_) + .setSampleShadingEnable(sample_shading_enable_) + .setMinSampleShading(min_sample_shading_) + .setAlphaToCoverageEnable(alpha_to_coverage_enable_) + .setAlphaToOneEnable(alpha_to_one_enable_); // 深度模板状态 - VkPipelineDepthStencilStateCreateInfo depth_stencil_info{}; - depth_stencil_info.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; - depth_stencil_info.depthTestEnable = depth_test_enable_ ? VK_TRUE : VK_FALSE; - depth_stencil_info.depthWriteEnable = depth_write_enable_ ? VK_TRUE : VK_FALSE; - depth_stencil_info.depthCompareOp = depth_compare_op_; - depth_stencil_info.depthBoundsTestEnable = depth_bounds_test_enable_ ? VK_TRUE : VK_FALSE; - depth_stencil_info.stencilTestEnable = stencil_test_enable_ ? VK_TRUE : VK_FALSE; - depth_stencil_info.front = stencil_front_; - depth_stencil_info.back = stencil_back_; - depth_stencil_info.minDepthBounds = min_depth_bounds_; - depth_stencil_info.maxDepthBounds = max_depth_bounds_; + vk::PipelineDepthStencilStateCreateInfo depth_stencil_info{}; + depth_stencil_info.setDepthTestEnable(depth_test_enable_) + .setDepthWriteEnable(depth_write_enable_) + .setDepthCompareOp(depth_compare_op_) + .setDepthBoundsTestEnable(depth_bounds_test_enable_) + .setStencilTestEnable(stencil_test_enable_) + .setFront(stencil_front_) + .setBack(stencil_back_) + .setMinDepthBounds(min_depth_bounds_) + .setMaxDepthBounds(max_depth_bounds_); // 颜色混合状态 - VkPipelineColorBlendStateCreateInfo color_blend_info{}; - color_blend_info.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; - color_blend_info.logicOpEnable = VK_FALSE; - color_blend_info.attachmentCount = static_cast(color_blend_attachments_.size()); - color_blend_info.pAttachments = color_blend_attachments_.data(); - color_blend_info.blendConstants[0] = blend_constants_[0]; - color_blend_info.blendConstants[1] = blend_constants_[1]; - color_blend_info.blendConstants[2] = blend_constants_[2]; - color_blend_info.blendConstants[3] = blend_constants_[3]; + vk::PipelineColorBlendStateCreateInfo color_blend_info{}; + color_blend_info.setLogicOpEnable(false) + .setAttachments(color_blend_attachments_) + .setBlendConstants(blend_constants_); // 动态状态 - VkPipelineDynamicStateCreateInfo dynamic_state_info{}; - dynamic_state_info.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; - dynamic_state_info.dynamicStateCount = static_cast(dynamic_states_.size()); - dynamic_state_info.pDynamicStates = dynamic_states_.data(); + vk::PipelineDynamicStateCreateInfo dynamic_state_info{}; + dynamic_state_info.setDynamicStates(dynamic_states_); // Dynamic Rendering 配置(Vulkan 1.3) - VkPipelineRenderingCreateInfo rendering_info{}; - rendering_info.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO; - rendering_info.colorAttachmentCount = static_cast(color_formats_.size()); - rendering_info.pColorAttachmentFormats = color_formats_.data(); - rendering_info.depthAttachmentFormat = depth_format_; - rendering_info.stencilAttachmentFormat = stencil_format_; + vk::PipelineRenderingCreateInfo rendering_info{}; + rendering_info.setColorAttachmentFormats(color_formats_) + .setDepthAttachmentFormat(depth_format_) + .setStencilAttachmentFormat(stencil_format_); // 创建管线 - VkGraphicsPipelineCreateInfo create_info{}; - create_info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; - create_info.pNext = &rendering_info; - create_info.stageCount = static_cast(shader_stages_.size()); - create_info.pStages = shader_stages_.data(); - create_info.pVertexInputState = &vertex_input_info; - create_info.pInputAssemblyState = &input_assembly_info; - create_info.pViewportState = &viewport_info; - create_info.pRasterizationState = &rasterization_info; - create_info.pMultisampleState = &multisample_info; - create_info.pDepthStencilState = &depth_stencil_info; - create_info.pColorBlendState = &color_blend_info; - create_info.pDynamicState = &dynamic_state_info; - create_info.layout = layout_; - create_info.renderPass = VK_NULL_HANDLE; // 使用 Dynamic Rendering - create_info.subpass = 0; + vk::GraphicsPipelineCreateInfo create_info{}; + create_info.setPNext(&rendering_info) + .setStages(shader_stages_) + .setPVertexInputState(&vertex_input_info) + .setPInputAssemblyState(&input_assembly_info) + .setPViewportState(&viewport_info) + .setPRasterizationState(&rasterization_info) + .setPMultisampleState(&multisample_info) + .setPDepthStencilState(&depth_stencil_info) + .setPColorBlendState(&color_blend_info) + .setPDynamicState(&dynamic_state_info) + .setLayout(layout_) + .setRenderPass(nullptr) // 使用 Dynamic Rendering + .setSubpass(0); - VkPipeline pipeline = VK_NULL_HANDLE; - VkResult result = vkCreateGraphicsPipelines(device_->get_device(), VK_NULL_HANDLE, 1, - &create_info, nullptr, &pipeline); + auto [result, pipeline] = device_->get_device().createGraphicsPipeline(nullptr, create_info); - if (result != VK_SUCCESS) { - LOG_ERROR("Failed to create graphics pipeline: {}", vk_result_to_string(result)); + if (result != vk::Result::eSuccess) { + MILAI_LOG_ERROR("Failed to create graphics pipeline: {}", vk::to_string(result)); return nullptr; } @@ -531,11 +507,11 @@ void graphics_pipeline_builder::reset() { shader_stages_.clear(); vertex_bindings_.clear(); vertex_attributes_.clear(); - topology_ = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; + topology_ = vk::PrimitiveTopology::eTriangleList; primitive_restart_enable_ = false; - polygon_mode_ = VK_POLYGON_MODE_FILL; - cull_mode_ = VK_CULL_MODE_BACK_BIT; - front_face_ = VK_FRONT_FACE_COUNTER_CLOCKWISE; + polygon_mode_ = vk::PolygonMode::eFill; + cull_mode_ = vk::CullModeFlagBits::eBack; + front_face_ = vk::FrontFace::eCounterClockwise; line_width_ = 1.0f; depth_clamp_enable_ = false; rasterizer_discard_enable_ = false; @@ -543,27 +519,27 @@ void graphics_pipeline_builder::reset() { depth_bias_constant_factor_ = 0.0f; depth_bias_clamp_ = 0.0f; depth_bias_slope_factor_ = 0.0f; - samples_ = VK_SAMPLE_COUNT_1_BIT; + samples_ = vk::SampleCountFlagBits::e1; sample_shading_enable_ = false; min_sample_shading_ = 1.0f; alpha_to_coverage_enable_ = false; alpha_to_one_enable_ = false; depth_test_enable_ = false; depth_write_enable_ = true; - depth_compare_op_ = VK_COMPARE_OP_LESS; + depth_compare_op_ = vk::CompareOp::eLess; depth_bounds_test_enable_ = false; min_depth_bounds_ = 0.0f; max_depth_bounds_ = 1.0f; stencil_test_enable_ = false; - stencil_front_ = {}; - stencil_back_ = {}; + stencil_front_ = vk::StencilOpState{}; + stencil_back_ = vk::StencilOpState{}; color_blend_attachments_.clear(); blend_constants_ = {0.0f, 0.0f, 0.0f, 0.0f}; - dynamic_states_ = {VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR}; + dynamic_states_ = {vk::DynamicState::eViewport, vk::DynamicState::eScissor}; color_formats_.clear(); - depth_format_ = VK_FORMAT_UNDEFINED; - stencil_format_ = VK_FORMAT_UNDEFINED; - layout_ = VK_NULL_HANDLE; + depth_format_ = vk::Format::eUndefined; + stencil_format_ = vk::Format::eUndefined; + layout_ = nullptr; } // ================================================================================================ @@ -571,8 +547,8 @@ void graphics_pipeline_builder::reset() { // ================================================================================================ graphics_pipeline::graphics_pipeline(std::shared_ptr device, - VkPipeline pipeline, - VkPipelineLayout layout) + vk::Pipeline pipeline, + vk::PipelineLayout layout) : device_(std::move(device)) , pipeline_(pipeline) , layout_(layout) @@ -580,9 +556,9 @@ graphics_pipeline::graphics_pipeline(std::shared_ptr device, } graphics_pipeline::~graphics_pipeline() { - if (pipeline_ != VK_NULL_HANDLE && device_ && device_->is_valid()) { - vkDestroyPipeline(device_->get_device(), pipeline_, nullptr); - pipeline_ = VK_NULL_HANDLE; + if (pipeline_ && device_ && device_->is_valid()) { + device_->get_device().destroyPipeline(pipeline_); + pipeline_ = nullptr; } } @@ -591,32 +567,32 @@ graphics_pipeline::graphics_pipeline(graphics_pipeline&& other) noexcept , pipeline_(other.pipeline_) , layout_(other.layout_) { - other.pipeline_ = VK_NULL_HANDLE; - other.layout_ = VK_NULL_HANDLE; + other.pipeline_ = nullptr; + other.layout_ = nullptr; } graphics_pipeline& graphics_pipeline::operator=(graphics_pipeline&& other) noexcept { if (this != &other) { - if (pipeline_ != VK_NULL_HANDLE && device_ && device_->is_valid()) { - vkDestroyPipeline(device_->get_device(), pipeline_, nullptr); + if (pipeline_ && device_ && device_->is_valid()) { + device_->get_device().destroyPipeline(pipeline_); } device_ = std::move(other.device_); pipeline_ = other.pipeline_; layout_ = other.layout_; - other.pipeline_ = VK_NULL_HANDLE; - other.layout_ = VK_NULL_HANDLE; + other.pipeline_ = nullptr; + other.layout_ = nullptr; } return *this; } void graphics_pipeline::on_created() { - LOG_DEBUG("Graphics pipeline created"); + MILAI_LOG_DEBUG("Graphics pipeline created"); } void graphics_pipeline::on_destroying() { - LOG_DEBUG("Graphics pipeline destroying"); + MILAI_LOG_DEBUG("Graphics pipeline destroying"); } // ================================================================================================ @@ -624,34 +600,32 @@ void graphics_pipeline::on_destroying() { // ================================================================================================ compute_pipeline::compute_pipeline(std::shared_ptr device, - VkShaderModule shader_module, - VkPipelineLayout layout, + vk::ShaderModule shader_module, + vk::PipelineLayout layout, const char* entry_point) : device_(std::move(device)) , layout_(layout) { - VkPipelineShaderStageCreateInfo stage_info{}; - stage_info.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - stage_info.stage = VK_SHADER_STAGE_COMPUTE_BIT; - stage_info.module = shader_module; - stage_info.pName = entry_point; + vk::PipelineShaderStageCreateInfo stage_info{}; + stage_info.setStage(vk::ShaderStageFlagBits::eCompute) + .setModule(shader_module) + .setPName(entry_point); - VkComputePipelineCreateInfo create_info{}; - create_info.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO; - create_info.stage = stage_info; - create_info.layout = layout; + vk::ComputePipelineCreateInfo create_info{}; + create_info.setStage(stage_info) + .setLayout(layout); - VkResult result = vkCreateComputePipelines(device_->get_device(), VK_NULL_HANDLE, 1, - &create_info, nullptr, &pipeline_); - if (result != VK_SUCCESS) { - LOG_ERROR("Failed to create compute pipeline: {}", vk_result_to_string(result)); + auto [result, pipeline] = device_->get_device().createComputePipeline(nullptr, create_info); + if (result != vk::Result::eSuccess) { + MILAI_LOG_ERROR("Failed to create compute pipeline: {}", vk::to_string(result)); } + pipeline_ = pipeline; } compute_pipeline::~compute_pipeline() { - if (pipeline_ != VK_NULL_HANDLE && device_ && device_->is_valid()) { - vkDestroyPipeline(device_->get_device(), pipeline_, nullptr); - pipeline_ = VK_NULL_HANDLE; + if (pipeline_ && device_ && device_->is_valid()) { + device_->get_device().destroyPipeline(pipeline_); + pipeline_ = nullptr; } } @@ -660,32 +634,32 @@ compute_pipeline::compute_pipeline(compute_pipeline&& other) noexcept , pipeline_(other.pipeline_) , layout_(other.layout_) { - other.pipeline_ = VK_NULL_HANDLE; - other.layout_ = VK_NULL_HANDLE; + other.pipeline_ = nullptr; + other.layout_ = nullptr; } compute_pipeline& compute_pipeline::operator=(compute_pipeline&& other) noexcept { if (this != &other) { - if (pipeline_ != VK_NULL_HANDLE && device_ && device_->is_valid()) { - vkDestroyPipeline(device_->get_device(), pipeline_, nullptr); + if (pipeline_ && device_ && device_->is_valid()) { + device_->get_device().destroyPipeline(pipeline_); } device_ = std::move(other.device_); pipeline_ = other.pipeline_; layout_ = other.layout_; - other.pipeline_ = VK_NULL_HANDLE; - other.layout_ = VK_NULL_HANDLE; + other.pipeline_ = nullptr; + other.layout_ = nullptr; } return *this; } void compute_pipeline::on_created() { - LOG_DEBUG("Compute pipeline created"); + MILAI_LOG_DEBUG("Compute pipeline created"); } void compute_pipeline::on_destroying() { - LOG_DEBUG("Compute pipeline destroying"); + MILAI_LOG_DEBUG("Compute pipeline destroying"); } } // namespace milai \ No newline at end of file diff --git a/src/render/pipeline.hpp b/src/render/pipeline.hpp index a6523dc..9b7d859 100644 --- a/src/render/pipeline.hpp +++ b/src/render/pipeline.hpp @@ -45,7 +45,7 @@ struct vertex_attribute { /// 绑定索引 u32 binding = 0; /// 格式 - VkFormat format = VK_FORMAT_R32G32B32_SFLOAT; + vk::Format format = vk::Format::eR32G32B32Sfloat; /// 偏移量 u32 offset = 0; }; @@ -59,7 +59,7 @@ struct vertex_binding { /// 步幅 u32 stride = 0; /// 输入率 - VkVertexInputRate input_rate = VK_VERTEX_INPUT_RATE_VERTEX; + vk::VertexInputRate input_rate = vk::VertexInputRate::eVertex; }; // ================================================================================================ @@ -71,9 +71,9 @@ struct vertex_binding { */ struct pipeline_layout_config { /// 描述符集布局列表 - std::vector descriptor_set_layouts; + std::vector descriptor_set_layouts; /// 推送常量范围列表 - std::vector push_constant_ranges; + std::vector push_constant_ranges; }; /** @@ -107,9 +107,9 @@ public: /** * @brief 获取管线布局句柄 - * @return VkPipelineLayout 句柄 + * @return vk::PipelineLayout 句柄 */ - [[nodiscard]] VkPipelineLayout get_vulkan_layout() const noexcept { + [[nodiscard]] vk::PipelineLayout get_vulkan_layout() const noexcept { return layout_; } @@ -118,13 +118,13 @@ public: * @return 如果有效返回 true */ [[nodiscard]] bool is_valid() const noexcept { - return layout_ != VK_NULL_HANDLE; + return !!layout_; } /** - * @brief 隐式转换为 VkPipelineLayout + * @brief 隐式转换为 vk::PipelineLayout */ - operator VkPipelineLayout() const noexcept { + operator vk::PipelineLayout() const noexcept { return layout_; } @@ -144,7 +144,7 @@ private: /// Vulkan 设备 std::shared_ptr device_; /// 管线布局句柄 - VkPipelineLayout layout_ = VK_NULL_HANDLE; + vk::PipelineLayout layout_; }; // ================================================================================================ @@ -193,7 +193,7 @@ public: * @param entry_point 入口点名称 * @return 自身引用 */ - graphics_pipeline_builder& set_vertex_shader(VkShaderModule module, + graphics_pipeline_builder& set_vertex_shader(vk::ShaderModule module, const char* entry_point = "main"); /** @@ -202,7 +202,7 @@ public: * @param entry_point 入口点名称 * @return 自身引用 */ - graphics_pipeline_builder& set_fragment_shader(VkShaderModule module, + graphics_pipeline_builder& set_fragment_shader(vk::ShaderModule module, const char* entry_point = "main"); /** @@ -211,7 +211,7 @@ public: * @param entry_point 入口点名称 * @return 自身引用 */ - graphics_pipeline_builder& set_geometry_shader(VkShaderModule module, + graphics_pipeline_builder& set_geometry_shader(vk::ShaderModule module, const char* entry_point = "main"); /** @@ -220,7 +220,7 @@ public: * @param entry_point 入口点名称 * @return 自身引用 */ - graphics_pipeline_builder& set_tessellation_control_shader(VkShaderModule module, + graphics_pipeline_builder& set_tessellation_control_shader(vk::ShaderModule module, const char* entry_point = "main"); /** @@ -229,7 +229,7 @@ public: * @param entry_point 入口点名称 * @return 自身引用 */ - graphics_pipeline_builder& set_tessellation_evaluation_shader(VkShaderModule module, + graphics_pipeline_builder& set_tessellation_evaluation_shader(vk::ShaderModule module, const char* entry_point = "main"); /** @@ -239,8 +239,8 @@ public: * @param entry_point 入口点名称 * @return 自身引用 */ - graphics_pipeline_builder& add_shader_stage(VkShaderStageFlagBits stage, - VkShaderModule module, + graphics_pipeline_builder& add_shader_stage(vk::ShaderStageFlagBits stage, + vk::ShaderModule module, const char* entry_point = "main"); // ============================================================================================ @@ -255,7 +255,7 @@ public: * @return 自身引用 */ graphics_pipeline_builder& add_vertex_binding(u32 binding, u32 stride, - VkVertexInputRate input_rate = VK_VERTEX_INPUT_RATE_VERTEX); + vk::VertexInputRate input_rate = vk::VertexInputRate::eVertex); /** * @brief 添加顶点属性 @@ -266,7 +266,7 @@ public: * @return 自身引用 */ graphics_pipeline_builder& add_vertex_attribute(u32 location, u32 binding, - VkFormat format, u32 offset); + vk::Format format, u32 offset); /** * @brief 设置顶点绑定列表 @@ -291,7 +291,7 @@ public: * @param topology 拓扑类型 * @return 自身引用 */ - graphics_pipeline_builder& set_topology(VkPrimitiveTopology topology); + graphics_pipeline_builder& set_topology(vk::PrimitiveTopology topology); /** * @brief 设置图元重启 @@ -309,21 +309,21 @@ public: * @param mode 多边形模式 * @return 自身引用 */ - graphics_pipeline_builder& set_polygon_mode(VkPolygonMode mode); + graphics_pipeline_builder& set_polygon_mode(vk::PolygonMode mode); /** * @brief 设置剔除模式 * @param cull_mode 剔除模式 * @return 自身引用 */ - graphics_pipeline_builder& set_cull_mode(VkCullModeFlags cull_mode); + graphics_pipeline_builder& set_cull_mode(vk::CullModeFlags cull_mode); /** * @brief 设置正面方向 * @param front_face 正面方向 * @return 自身引用 */ - graphics_pipeline_builder& set_front_face(VkFrontFace front_face); + graphics_pipeline_builder& set_front_face(vk::FrontFace front_face); /** * @brief 设置线宽 @@ -366,7 +366,7 @@ public: * @param samples 采样数 * @return 自身引用 */ - graphics_pipeline_builder& set_samples(VkSampleCountFlagBits samples); + graphics_pipeline_builder& set_samples(vk::SampleCountFlagBits samples); /** * @brief 启用采样着色 @@ -400,8 +400,8 @@ public: * @param compare_op 比较操作 * @return 自身引用 */ - graphics_pipeline_builder& enable_depth_test(bool enable, - VkCompareOp compare_op = VK_COMPARE_OP_LESS); + graphics_pipeline_builder& enable_depth_test(bool enable, + vk::CompareOp compare_op = vk::CompareOp::eLess); /** * @brief 启用深度写入 @@ -433,8 +433,8 @@ public: * @param back 背面操作 * @return 自身引用 */ - graphics_pipeline_builder& set_stencil_op(const VkStencilOpState& front, - const VkStencilOpState& back); + graphics_pipeline_builder& set_stencil_op(const vk::StencilOpState& front, + const vk::StencilOpState& back); // ============================================================================================ // 颜色混合设置 @@ -455,8 +455,8 @@ public: * @param dst_alpha 目标 Alpha 因子 * @return 自身引用 */ - graphics_pipeline_builder& set_blend_factors(VkBlendFactor src_color, VkBlendFactor dst_color, - VkBlendFactor src_alpha, VkBlendFactor dst_alpha); + graphics_pipeline_builder& set_blend_factors(vk::BlendFactor src_color, vk::BlendFactor dst_color, + vk::BlendFactor src_alpha, vk::BlendFactor dst_alpha); /** * @brief 设置混合操作 @@ -464,14 +464,14 @@ public: * @param alpha_op Alpha 操作 * @return 自身引用 */ - graphics_pipeline_builder& set_blend_op(VkBlendOp color_op, VkBlendOp alpha_op); + graphics_pipeline_builder& set_blend_op(vk::BlendOp color_op, vk::BlendOp alpha_op); /** * @brief 设置颜色写掩码 * @param mask 掩码 * @return 自身引用 */ - graphics_pipeline_builder& set_color_write_mask(VkColorComponentFlags mask); + graphics_pipeline_builder& set_color_write_mask(vk::ColorComponentFlags mask); /** * @brief 添加颜色附件混合状态 @@ -479,7 +479,7 @@ public: * @return 自身引用 */ graphics_pipeline_builder& add_color_blend_attachment( - const VkPipelineColorBlendAttachmentState& attachment); + const vk::PipelineColorBlendAttachmentState& attachment); /** * @brief 设置混合常量 @@ -500,14 +500,14 @@ public: * @param state 动态状态 * @return 自身引用 */ - graphics_pipeline_builder& add_dynamic_state(VkDynamicState state); + graphics_pipeline_builder& add_dynamic_state(vk::DynamicState state); /** * @brief 设置动态状态列表 * @param states 动态状态列表 * @return 自身引用 */ - graphics_pipeline_builder& set_dynamic_states(std::span states); + graphics_pipeline_builder& set_dynamic_states(std::span states); // ============================================================================================ // 渲染格式设置(Dynamic Rendering) @@ -518,35 +518,35 @@ public: * @param format 格式 * @return 自身引用 */ - graphics_pipeline_builder& set_color_format(VkFormat format); + graphics_pipeline_builder& set_color_format(vk::Format format); /** * @brief 添加颜色附件格式 * @param format 格式 * @return 自身引用 */ - graphics_pipeline_builder& add_color_format(VkFormat format); + graphics_pipeline_builder& add_color_format(vk::Format format); /** * @brief 设置颜色附件格式列表 * @param formats 格式列表 * @return 自身引用 */ - graphics_pipeline_builder& set_color_formats(std::span formats); + graphics_pipeline_builder& set_color_formats(std::span formats); /** * @brief 设置深度格式 * @param format 格式 * @return 自身引用 */ - graphics_pipeline_builder& set_depth_format(VkFormat format); + graphics_pipeline_builder& set_depth_format(vk::Format format); /** * @brief 设置模板格式 * @param format 格式 * @return 自身引用 */ - graphics_pipeline_builder& set_stencil_format(VkFormat format); + graphics_pipeline_builder& set_stencil_format(vk::Format format); // ============================================================================================ // 布局设置 @@ -557,7 +557,7 @@ public: * @param layout 管线布局 * @return 自身引用 */ - graphics_pipeline_builder& set_layout(VkPipelineLayout layout); + graphics_pipeline_builder& set_layout(vk::PipelineLayout layout); /** * @brief 设置管线布局 @@ -586,28 +586,28 @@ private: std::shared_ptr device_; /// 着色器阶段 - std::vector shader_stages_; + std::vector shader_stages_; /// 顶点绑定描述 - std::vector vertex_bindings_; + std::vector vertex_bindings_; /// 顶点属性描述 - std::vector vertex_attributes_; + std::vector vertex_attributes_; /// 图元拓扑 - VkPrimitiveTopology topology_ = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; + vk::PrimitiveTopology topology_ = vk::PrimitiveTopology::eTriangleList; /// 图元重启 bool primitive_restart_enable_ = false; /// 多边形模式 - VkPolygonMode polygon_mode_ = VK_POLYGON_MODE_FILL; + vk::PolygonMode polygon_mode_ = vk::PolygonMode::eFill; /// 剔除模式 - VkCullModeFlags cull_mode_ = VK_CULL_MODE_BACK_BIT; + vk::CullModeFlags cull_mode_ = vk::CullModeFlagBits::eBack; /// 正面方向 - VkFrontFace front_face_ = VK_FRONT_FACE_COUNTER_CLOCKWISE; + vk::FrontFace front_face_ = vk::FrontFace::eCounterClockwise; /// 线宽 f32 line_width_ = 1.0f; @@ -625,7 +625,7 @@ private: f32 depth_bias_slope_factor_ = 0.0f; /// 采样数 - VkSampleCountFlagBits samples_ = VK_SAMPLE_COUNT_1_BIT; + vk::SampleCountFlagBits samples_ = vk::SampleCountFlagBits::e1; /// 采样着色 bool sample_shading_enable_ = false; @@ -640,7 +640,7 @@ private: /// 深度测试 bool depth_test_enable_ = false; bool depth_write_enable_ = true; - VkCompareOp depth_compare_op_ = VK_COMPARE_OP_LESS; + vk::CompareOp depth_compare_op_ = vk::CompareOp::eLess; /// 深度边界 bool depth_bounds_test_enable_ = false; @@ -649,29 +649,29 @@ private: /// 模板测试 bool stencil_test_enable_ = false; - VkStencilOpState stencil_front_{}; - VkStencilOpState stencil_back_{}; + vk::StencilOpState stencil_front_{}; + vk::StencilOpState stencil_back_{}; /// 颜色混合附件 - std::vector color_blend_attachments_; + std::vector color_blend_attachments_; /// 混合常量 std::array blend_constants_ = {0.0f, 0.0f, 0.0f, 0.0f}; /// 动态状态 - std::vector dynamic_states_; + std::vector dynamic_states_; /// 颜色格式 - std::vector color_formats_; + std::vector color_formats_; /// 深度格式 - VkFormat depth_format_ = VK_FORMAT_UNDEFINED; + vk::Format depth_format_ = vk::Format::eUndefined; /// 模板格式 - VkFormat stencil_format_ = VK_FORMAT_UNDEFINED; + vk::Format stencil_format_ = vk::Format::eUndefined; /// 管线布局 - VkPipelineLayout layout_ = VK_NULL_HANDLE; + vk::PipelineLayout layout_; }; // ================================================================================================ @@ -691,9 +691,9 @@ public: * @param pipeline 管线句柄 * @param layout 管线布局句柄 */ - graphics_pipeline(std::shared_ptr device, - VkPipeline pipeline, - VkPipelineLayout layout); + graphics_pipeline(std::shared_ptr device, + vk::Pipeline pipeline, + vk::PipelineLayout layout); /** * @brief 析构函数 @@ -710,17 +710,17 @@ public: /** * @brief 获取管线句柄 - * @return VkPipeline 句柄 + * @return vk::Pipeline 句柄 */ - [[nodiscard]] VkPipeline get_vulkan_pipeline() const noexcept { + [[nodiscard]] vk::Pipeline get_vulkan_pipeline() const noexcept { return pipeline_; } /** * @brief 获取管线布局句柄 - * @return VkPipelineLayout 句柄 + * @return vk::PipelineLayout 句柄 */ - [[nodiscard]] VkPipelineLayout get_layout() const noexcept { + [[nodiscard]] vk::PipelineLayout get_layout() const noexcept { return layout_; } @@ -729,13 +729,13 @@ public: * @return 如果有效返回 true */ [[nodiscard]] bool is_valid() const noexcept { - return pipeline_ != VK_NULL_HANDLE; + return !!pipeline_; } /** - * @brief 隐式转换为 VkPipeline + * @brief 隐式转换为 vk::Pipeline */ - operator VkPipeline() const noexcept { + operator vk::Pipeline() const noexcept { return pipeline_; } @@ -755,9 +755,9 @@ private: /// Vulkan 设备 std::shared_ptr device_; /// 管线句柄 - VkPipeline pipeline_ = VK_NULL_HANDLE; + vk::Pipeline pipeline_; /// 管线布局句柄 - VkPipelineLayout layout_ = VK_NULL_HANDLE; + vk::PipelineLayout layout_; }; // ================================================================================================ @@ -779,8 +779,8 @@ public: * @param entry_point 入口点名称 */ compute_pipeline(std::shared_ptr device, - VkShaderModule shader_module, - VkPipelineLayout layout, + vk::ShaderModule shader_module, + vk::PipelineLayout layout, const char* entry_point = "main"); /** @@ -798,17 +798,17 @@ public: /** * @brief 获取管线句柄 - * @return VkPipeline 句柄 + * @return vk::Pipeline 句柄 */ - [[nodiscard]] VkPipeline get_vulkan_pipeline() const noexcept { + [[nodiscard]] vk::Pipeline get_vulkan_pipeline() const noexcept { return pipeline_; } /** * @brief 获取管线布局句柄 - * @return VkPipelineLayout 句柄 + * @return vk::PipelineLayout 句柄 */ - [[nodiscard]] VkPipelineLayout get_layout() const noexcept { + [[nodiscard]] vk::PipelineLayout get_layout() const noexcept { return layout_; } @@ -817,13 +817,13 @@ public: * @return 如果有效返回 true */ [[nodiscard]] bool is_valid() const noexcept { - return pipeline_ != VK_NULL_HANDLE; + return !!pipeline_; } /** - * @brief 隐式转换为 VkPipeline + * @brief 隐式转换为 vk::Pipeline */ - operator VkPipeline() const noexcept { + operator vk::Pipeline() const noexcept { return pipeline_; } @@ -843,9 +843,9 @@ private: /// Vulkan 设备 std::shared_ptr device_; /// 管线句柄 - VkPipeline pipeline_ = VK_NULL_HANDLE; + vk::Pipeline pipeline_; /// 管线布局句柄 - VkPipelineLayout layout_ = VK_NULL_HANDLE; + vk::PipelineLayout layout_; }; } // namespace milai \ No newline at end of file diff --git a/src/render/render_pass.cpp b/src/render/render_pass.cpp index e254e67..3c75ab4 100644 --- a/src/render/render_pass.cpp +++ b/src/render/render_pass.cpp @@ -21,16 +21,15 @@ rendering_info::rendering_info(const render_target& target) { // 添加颜色附件 for (const auto& attachment : target.color_attachments) { - VkRenderingAttachmentInfo info{}; - info.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO; + vk::RenderingAttachmentInfo info{}; info.imageView = attachment.image_view; info.imageLayout = attachment.image_layout; - info.loadOp = static_cast(attachment.load_op); - info.storeOp = static_cast(attachment.store_op); + info.loadOp = static_cast(attachment.load_op); + info.storeOp = static_cast(attachment.store_op); info.clearValue.color = attachment.clear_value.to_vulkan(); // 解析附件(用于 MSAA) - if (attachment.resolve_image_view != VK_NULL_HANDLE) { + if (attachment.resolve_image_view) { info.resolveMode = attachment.resolve_mode; info.resolveImageView = attachment.resolve_image_view; info.resolveImageLayout = attachment.resolve_image_layout; @@ -42,11 +41,10 @@ rendering_info::rendering_info(const render_target& target) { // 设置深度附件 if (target.depth_attachment.has_value()) { const auto& attachment = target.depth_attachment.value(); - depth_attachment_.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO; depth_attachment_.imageView = attachment.image_view; depth_attachment_.imageLayout = attachment.image_layout; - depth_attachment_.loadOp = static_cast(attachment.load_op); - depth_attachment_.storeOp = static_cast(attachment.store_op); + depth_attachment_.loadOp = static_cast(attachment.load_op); + depth_attachment_.storeOp = static_cast(attachment.store_op); depth_attachment_.clearValue.depthStencil = attachment.clear_depth_stencil_value.to_vulkan(); has_depth_ = true; } @@ -54,11 +52,10 @@ rendering_info::rendering_info(const render_target& target) { // 设置模板附件 if (target.stencil_attachment.has_value()) { const auto& attachment = target.stencil_attachment.value(); - stencil_attachment_.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO; stencil_attachment_.imageView = attachment.image_view; stencil_attachment_.imageLayout = attachment.image_layout; - stencil_attachment_.loadOp = static_cast(attachment.load_op); - stencil_attachment_.storeOp = static_cast(attachment.store_op); + stencil_attachment_.loadOp = static_cast(attachment.load_op); + stencil_attachment_.storeOp = static_cast(attachment.store_op); stencil_attachment_.clearValue.depthStencil = attachment.clear_depth_stencil_value.to_vulkan(); has_stencil_ = true; } @@ -67,42 +64,41 @@ rendering_info::rendering_info(const render_target& target) { } rendering_info& rendering_info::set_render_area(i32 x, i32 y, u32 width, u32 height) { - render_area_.offset = {x, y}; - render_area_.extent = {width, height}; + render_area_.offset = vk::Offset2D{x, y}; + render_area_.extent = vk::Extent2D{width, height}; built_ = false; return *this; } -rendering_info& rendering_info::set_render_area(VkRect2D area) { +rendering_info& rendering_info::set_render_area(vk::Rect2D area) { render_area_ = area; built_ = false; return *this; } -rendering_info& rendering_info::set_render_area(VkExtent2D extent) { - render_area_.offset = {0, 0}; +rendering_info& rendering_info::set_render_area(vk::Extent2D extent) { + render_area_.offset = vk::Offset2D{0, 0}; render_area_.extent = extent; built_ = false; return *this; } rendering_info& rendering_info::add_color_attachment( - VkImageView image_view, - VkImageLayout layout, + vk::ImageView image_view, + vk::ImageLayout layout, attachment_load_op load_op, attachment_store_op store_op, const clear_color& clear_value) { - VkRenderingAttachmentInfo info{}; - info.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO; + vk::RenderingAttachmentInfo info{}; info.imageView = image_view; info.imageLayout = layout; - info.loadOp = static_cast(load_op); - info.storeOp = static_cast(store_op); + info.loadOp = static_cast(load_op); + info.storeOp = static_cast(store_op); info.clearValue.color = clear_value.to_vulkan(); - info.resolveMode = VK_RESOLVE_MODE_NONE; - info.resolveImageView = VK_NULL_HANDLE; - info.resolveImageLayout = VK_IMAGE_LAYOUT_UNDEFINED; + info.resolveMode = vk::ResolveModeFlagBits::eNone; + info.resolveImageView = nullptr; + info.resolveImageLayout = vk::ImageLayout::eUndefined; color_attachments_.push_back(info); built_ = false; @@ -110,23 +106,22 @@ rendering_info& rendering_info::add_color_attachment( } rendering_info& rendering_info::add_color_attachment_with_resolve( - VkImageView image_view, - VkImageView resolve_view, - VkImageLayout layout, + vk::ImageView image_view, + vk::ImageView resolve_view, + vk::ImageLayout layout, attachment_load_op load_op, attachment_store_op store_op, const clear_color& clear_value) { - VkRenderingAttachmentInfo info{}; - info.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO; + vk::RenderingAttachmentInfo info{}; info.imageView = image_view; info.imageLayout = layout; - info.loadOp = static_cast(load_op); - info.storeOp = static_cast(store_op); + info.loadOp = static_cast(load_op); + info.storeOp = static_cast(store_op); info.clearValue.color = clear_value.to_vulkan(); - info.resolveMode = VK_RESOLVE_MODE_AVERAGE_BIT; + info.resolveMode = vk::ResolveModeFlagBits::eAverage; info.resolveImageView = resolve_view; - info.resolveImageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + info.resolveImageLayout = vk::ImageLayout::eColorAttachmentOptimal; color_attachments_.push_back(info); built_ = false; @@ -134,18 +129,17 @@ rendering_info& rendering_info::add_color_attachment_with_resolve( } rendering_info& rendering_info::set_depth_attachment( - VkImageView image_view, - VkImageLayout layout, + vk::ImageView image_view, + vk::ImageLayout layout, attachment_load_op load_op, attachment_store_op store_op, f32 clear_value) { - depth_attachment_ = {}; - depth_attachment_.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO; + depth_attachment_ = vk::RenderingAttachmentInfo{}; depth_attachment_.imageView = image_view; depth_attachment_.imageLayout = layout; - depth_attachment_.loadOp = static_cast(load_op); - depth_attachment_.storeOp = static_cast(store_op); + depth_attachment_.loadOp = static_cast(load_op); + depth_attachment_.storeOp = static_cast(store_op); depth_attachment_.clearValue.depthStencil.depth = clear_value; depth_attachment_.clearValue.depthStencil.stencil = 0; @@ -155,18 +149,17 @@ rendering_info& rendering_info::set_depth_attachment( } rendering_info& rendering_info::set_stencil_attachment( - VkImageView image_view, - VkImageLayout layout, + vk::ImageView image_view, + vk::ImageLayout layout, attachment_load_op load_op, attachment_store_op store_op, u32 clear_value) { - stencil_attachment_ = {}; - stencil_attachment_.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO; + stencil_attachment_ = vk::RenderingAttachmentInfo{}; stencil_attachment_.imageView = image_view; stencil_attachment_.imageLayout = layout; - stencil_attachment_.loadOp = static_cast(load_op); - stencil_attachment_.storeOp = static_cast(store_op); + stencil_attachment_.loadOp = static_cast(load_op); + stencil_attachment_.storeOp = static_cast(store_op); stencil_attachment_.clearValue.depthStencil.depth = 0.0f; stencil_attachment_.clearValue.depthStencil.stencil = clear_value; @@ -176,8 +169,8 @@ rendering_info& rendering_info::set_stencil_attachment( } rendering_info& rendering_info::set_depth_stencil_attachment( - VkImageView image_view, - VkImageLayout layout, + vk::ImageView image_view, + vk::ImageLayout layout, attachment_load_op depth_load_op, attachment_store_op depth_store_op, attachment_load_op stencil_load_op, @@ -186,21 +179,19 @@ rendering_info& rendering_info::set_depth_stencil_attachment( u32 clear_stencil) { // 深度和模板使用相同的图像视图 - depth_attachment_ = {}; - depth_attachment_.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO; + depth_attachment_ = vk::RenderingAttachmentInfo{}; depth_attachment_.imageView = image_view; depth_attachment_.imageLayout = layout; - depth_attachment_.loadOp = static_cast(depth_load_op); - depth_attachment_.storeOp = static_cast(depth_store_op); + depth_attachment_.loadOp = static_cast(depth_load_op); + depth_attachment_.storeOp = static_cast(depth_store_op); depth_attachment_.clearValue.depthStencil.depth = clear_depth; depth_attachment_.clearValue.depthStencil.stencil = clear_stencil; - stencil_attachment_ = {}; - stencil_attachment_.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO; + stencil_attachment_ = vk::RenderingAttachmentInfo{}; stencil_attachment_.imageView = image_view; stencil_attachment_.imageLayout = layout; - stencil_attachment_.loadOp = static_cast(stencil_load_op); - stencil_attachment_.storeOp = static_cast(stencil_store_op); + stencil_attachment_.loadOp = static_cast(stencil_load_op); + stencil_attachment_.storeOp = static_cast(stencil_store_op); stencil_attachment_.clearValue.depthStencil.depth = clear_depth; stencil_attachment_.clearValue.depthStencil.stencil = clear_stencil; @@ -222,27 +213,27 @@ rendering_info& rendering_info::set_view_mask(u32 mask) { return *this; } -rendering_info& rendering_info::set_flags(VkRenderingFlags flags) { +rendering_info& rendering_info::set_flags(vk::RenderingFlags flags) { flags_ = flags; built_ = false; return *this; } void rendering_info::clear() { - render_area_ = {}; + render_area_ = vk::Rect2D{}; layer_count_ = 1; view_mask_ = 0; - flags_ = 0; + flags_ = vk::RenderingFlags{}; color_attachments_.clear(); - depth_attachment_ = {}; - stencil_attachment_ = {}; + depth_attachment_ = vk::RenderingAttachmentInfo{}; + stencil_attachment_ = vk::RenderingAttachmentInfo{}; has_depth_ = false; has_stencil_ = false; - rendering_info_ = {}; + rendering_info_ = vk::RenderingInfo{}; built_ = false; } -const VkRenderingInfo* rendering_info::get_vulkan_rendering_info() { +const vk::RenderingInfo* rendering_info::get_vulkan_rendering_info() { if (!built_) { build(); } @@ -250,8 +241,7 @@ const VkRenderingInfo* rendering_info::get_vulkan_rendering_info() { } void rendering_info::build() { - rendering_info_ = {}; - rendering_info_.sType = VK_STRUCTURE_TYPE_RENDERING_INFO; + rendering_info_ = vk::RenderingInfo{}; rendering_info_.flags = flags_; rendering_info_.renderArea = render_area_; rendering_info_.layerCount = layer_count_; @@ -269,19 +259,19 @@ void rendering_info::build() { // ================================================================================================ render_target_builder::render_target_builder(u32 width, u32 height) { - target_.render_area.offset = {0, 0}; - target_.render_area.extent = {width, height}; + target_.render_area.offset = vk::Offset2D{0, 0}; + target_.render_area.extent = vk::Extent2D{width, height}; } render_target_builder& render_target_builder::add_color_attachment( - VkImageView image_view, + vk::ImageView image_view, const clear_color& clear_value, attachment_load_op load_op, attachment_store_op store_op) { render_attachment attachment{}; attachment.image_view = image_view; - attachment.image_layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + attachment.image_layout = vk::ImageLayout::eColorAttachmentOptimal; attachment.load_op = load_op; attachment.store_op = store_op; attachment.clear_value = clear_value; @@ -291,35 +281,35 @@ render_target_builder& render_target_builder::add_color_attachment( } render_target_builder& render_target_builder::add_color_attachment_msaa( - VkImageView image_view, - VkImageView resolve_view, + vk::ImageView image_view, + vk::ImageView resolve_view, const clear_color& clear_value, attachment_load_op load_op, attachment_store_op store_op) { render_attachment attachment{}; attachment.image_view = image_view; - attachment.image_layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + attachment.image_layout = vk::ImageLayout::eColorAttachmentOptimal; attachment.load_op = load_op; attachment.store_op = store_op; attachment.clear_value = clear_value; attachment.resolve_image_view = resolve_view; - attachment.resolve_image_layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - attachment.resolve_mode = VK_RESOLVE_MODE_AVERAGE_BIT; + attachment.resolve_image_layout = vk::ImageLayout::eColorAttachmentOptimal; + attachment.resolve_mode = vk::ResolveModeFlagBits::eAverage; target_.color_attachments.push_back(attachment); return *this; } render_target_builder& render_target_builder::set_depth_attachment( - VkImageView image_view, + vk::ImageView image_view, f32 clear_value, attachment_load_op load_op, attachment_store_op store_op) { render_attachment attachment{}; attachment.image_view = image_view; - attachment.image_layout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL; + attachment.image_layout = vk::ImageLayout::eDepthAttachmentOptimal; attachment.load_op = load_op; attachment.store_op = store_op; attachment.clear_depth_stencil_value.depth = clear_value; @@ -329,14 +319,14 @@ render_target_builder& render_target_builder::set_depth_attachment( } render_target_builder& render_target_builder::set_depth_stencil_attachment( - VkImageView image_view, + vk::ImageView image_view, f32 clear_depth, u32 clear_stencil) { // 深度附件 render_attachment depth_attachment{}; depth_attachment.image_view = image_view; - depth_attachment.image_layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + depth_attachment.image_layout = vk::ImageLayout::eDepthStencilAttachmentOptimal; depth_attachment.load_op = attachment_load_op::clear; depth_attachment.store_op = attachment_store_op::store; depth_attachment.clear_depth_stencil_value.depth = clear_depth; @@ -346,7 +336,7 @@ render_target_builder& render_target_builder::set_depth_stencil_attachment( // 模板附件 render_attachment stencil_attachment{}; stencil_attachment.image_view = image_view; - stencil_attachment.image_layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + stencil_attachment.image_layout = vk::ImageLayout::eDepthStencilAttachmentOptimal; stencil_attachment.load_op = attachment_load_op::clear; stencil_attachment.store_op = attachment_store_op::dont_care; stencil_attachment.clear_depth_stencil_value.depth = clear_depth; @@ -370,8 +360,8 @@ render_target render_target_builder::build() const { // ================================================================================================ render_target make_color_render_target( - VkImageView image_view, - VkExtent2D extent, + vk::ImageView image_view, + vk::Extent2D extent, const clear_color& clear_value) { return render_target_builder(extent.width, extent.height) @@ -380,9 +370,9 @@ render_target make_color_render_target( } render_target make_color_depth_render_target( - VkImageView color_view, - VkImageView depth_view, - VkExtent2D extent, + vk::ImageView color_view, + vk::ImageView depth_view, + vk::Extent2D extent, const clear_color& clear_value, f32 clear_depth) { diff --git a/src/render/render_pass.hpp b/src/render/render_pass.hpp index 0b0f094..75232ab 100644 --- a/src/render/render_pass.hpp +++ b/src/render/render_pass.hpp @@ -13,7 +13,6 @@ #include "vulkan_types.hpp" #include "types.hpp" -#include #include #include #include @@ -25,11 +24,11 @@ namespace milai { */ enum class attachment_load_op { /// 加载现有内容 - load = VK_ATTACHMENT_LOAD_OP_LOAD, + load = static_cast(vk::AttachmentLoadOp::eLoad), /// 清除为指定值 - clear = VK_ATTACHMENT_LOAD_OP_CLEAR, + clear = static_cast(vk::AttachmentLoadOp::eClear), /// 内容不关心 - dont_care = VK_ATTACHMENT_LOAD_OP_DONT_CARE + dont_care = static_cast(vk::AttachmentLoadOp::eDontCare) }; /** @@ -37,11 +36,11 @@ enum class attachment_load_op { */ enum class attachment_store_op { /// 存储渲染结果 - store = VK_ATTACHMENT_STORE_OP_STORE, + store = static_cast(vk::AttachmentStoreOp::eStore), /// 内容不需要保留 - dont_care = VK_ATTACHMENT_STORE_OP_DONT_CARE, + dont_care = static_cast(vk::AttachmentStoreOp::eDontCare), /// 无(仅用于深度/模板附件) - none = VK_ATTACHMENT_STORE_OP_NONE + none = static_cast(vk::AttachmentStoreOp::eNone) }; /** @@ -73,13 +72,8 @@ struct clear_color { * @brief 转换为 VkClearColorValue * @return VkClearColorValue */ - [[nodiscard]] VkClearColorValue to_vulkan() const { - VkClearColorValue value{}; - value.float32[0] = r; - value.float32[1] = g; - value.float32[2] = b; - value.float32[3] = a; - return value; + [[nodiscard]] vk::ClearColorValue to_vulkan() const { + return vk::ClearColorValue{std::array{r, g, b, a}}; } /// 预定义颜色 @@ -118,11 +112,8 @@ struct clear_depth_stencil { * @brief 转换为 VkClearDepthStencilValue * @return VkClearDepthStencilValue */ - [[nodiscard]] VkClearDepthStencilValue to_vulkan() const { - VkClearDepthStencilValue value{}; - value.depth = depth; - value.stencil = stencil; - return value; + [[nodiscard]] vk::ClearDepthStencilValue to_vulkan() const { + return vk::ClearDepthStencilValue{depth, stencil}; } }; @@ -131,10 +122,10 @@ struct clear_depth_stencil { */ struct render_attachment { /// 图像视图 - VkImageView image_view = VK_NULL_HANDLE; + vk::ImageView image_view; /// 图像布局 - VkImageLayout image_layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + vk::ImageLayout image_layout = vk::ImageLayout::eColorAttachmentOptimal; /// 加载操作 attachment_load_op load_op = attachment_load_op::clear; @@ -149,13 +140,13 @@ struct render_attachment { clear_depth_stencil clear_depth_stencil_value{}; /// 解析图像视图(用于 MSAA) - VkImageView resolve_image_view = VK_NULL_HANDLE; + vk::ImageView resolve_image_view; /// 解析图像布局 - VkImageLayout resolve_image_layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + vk::ImageLayout resolve_image_layout = vk::ImageLayout::eColorAttachmentOptimal; /// 解析模式 - VkResolveModeFlagBits resolve_mode = VK_RESOLVE_MODE_NONE; + vk::ResolveModeFlagBits resolve_mode = vk::ResolveModeFlagBits::eNone; }; /** @@ -174,7 +165,7 @@ struct render_target { std::optional stencil_attachment; /// 渲染区域 - VkRect2D render_area{}; + vk::Rect2D render_area{}; /// 多视图层数 u32 layer_count = 1; @@ -221,8 +212,8 @@ struct render_target { * @return 自身引用 */ render_target& set_render_area(i32 x, i32 y, u32 width, u32 height) { - render_area.offset = {x, y}; - render_area.extent = {width, height}; + render_area.offset = vk::Offset2D{x, y}; + render_area.extent = vk::Extent2D{width, height}; return *this; } @@ -231,8 +222,8 @@ struct render_target { * @param extent 尺寸 * @return 自身引用 */ - render_target& set_render_area(VkExtent2D extent) { - render_area.offset = {0, 0}; + render_target& set_render_area(vk::Extent2D extent) { + render_area.offset = vk::Offset2D{0, 0}; render_area.extent = extent; return *this; } @@ -271,14 +262,14 @@ public: * @param area 渲染区域 * @return 自身引用 */ - rendering_info& set_render_area(VkRect2D area); + rendering_info& set_render_area(vk::Rect2D area); /** * @brief 设置渲染区域(从尺寸) * @param extent 尺寸 * @return 自身引用 */ - rendering_info& set_render_area(VkExtent2D extent); + rendering_info& set_render_area(vk::Extent2D extent); /** * @brief 添加颜色附件 @@ -290,8 +281,8 @@ public: * @return 自身引用 */ rendering_info& add_color_attachment( - VkImageView image_view, - VkImageLayout layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + vk::ImageView image_view, + vk::ImageLayout layout = vk::ImageLayout::eColorAttachmentOptimal, attachment_load_op load_op = attachment_load_op::clear, attachment_store_op store_op = attachment_store_op::store, const clear_color& clear_value = clear_color::black()); @@ -307,9 +298,9 @@ public: * @return 自身引用 */ rendering_info& add_color_attachment_with_resolve( - VkImageView image_view, - VkImageView resolve_view, - VkImageLayout layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + vk::ImageView image_view, + vk::ImageView resolve_view, + vk::ImageLayout layout = vk::ImageLayout::eColorAttachmentOptimal, attachment_load_op load_op = attachment_load_op::clear, attachment_store_op store_op = attachment_store_op::store, const clear_color& clear_value = clear_color::black()); @@ -324,8 +315,8 @@ public: * @return 自身引用 */ rendering_info& set_depth_attachment( - VkImageView image_view, - VkImageLayout layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, + vk::ImageView image_view, + vk::ImageLayout layout = vk::ImageLayout::eDepthStencilAttachmentOptimal, attachment_load_op load_op = attachment_load_op::clear, attachment_store_op store_op = attachment_store_op::store, f32 clear_value = 1.0f); @@ -340,8 +331,8 @@ public: * @return 自身引用 */ rendering_info& set_stencil_attachment( - VkImageView image_view, - VkImageLayout layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, + vk::ImageView image_view, + vk::ImageLayout layout = vk::ImageLayout::eDepthStencilAttachmentOptimal, attachment_load_op load_op = attachment_load_op::clear, attachment_store_op store_op = attachment_store_op::dont_care, u32 clear_value = 0); @@ -359,8 +350,8 @@ public: * @return 自身引用 */ rendering_info& set_depth_stencil_attachment( - VkImageView image_view, - VkImageLayout layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, + vk::ImageView image_view, + vk::ImageLayout layout = vk::ImageLayout::eDepthStencilAttachmentOptimal, attachment_load_op depth_load_op = attachment_load_op::clear, attachment_store_op depth_store_op = attachment_store_op::store, attachment_load_op stencil_load_op = attachment_load_op::dont_care, @@ -387,7 +378,7 @@ public: * @param flags 渲染标志 * @return 自身引用 */ - rendering_info& set_flags(VkRenderingFlags flags); + rendering_info& set_flags(vk::RenderingFlags flags); /** * @brief 清除所有附件 @@ -398,7 +389,7 @@ public: * @brief 获取 Vulkan 渲染信息 * @return VkRenderingInfo 指针 */ - [[nodiscard]] const VkRenderingInfo* get_vulkan_rendering_info(); + [[nodiscard]] const vk::RenderingInfo* get_vulkan_rendering_info(); /** * @brief 获取颜色附件数量 @@ -424,7 +415,7 @@ public: * @brief 获取渲染区域 * @return 渲染区域 */ - [[nodiscard]] VkRect2D get_render_area() const { return render_area_; } + [[nodiscard]] vk::Rect2D get_render_area() const { return render_area_; } private: /** @@ -433,7 +424,7 @@ private: void build(); /// 渲染区域 - VkRect2D render_area_{}; + vk::Rect2D render_area_{}; /// 层数 u32 layer_count_ = 1; @@ -442,16 +433,16 @@ private: u32 view_mask_ = 0; /// 渲染标志 - VkRenderingFlags flags_ = 0; + vk::RenderingFlags flags_{}; /// 颜色附件信息 - std::vector color_attachments_; + std::vector color_attachments_; /// 深度附件信息 - VkRenderingAttachmentInfo depth_attachment_{}; + vk::RenderingAttachmentInfo depth_attachment_{}; /// 模板附件信息 - VkRenderingAttachmentInfo stencil_attachment_{}; + vk::RenderingAttachmentInfo stencil_attachment_{}; /// 是否有深度附件 bool has_depth_ = false; @@ -460,7 +451,7 @@ private: bool has_stencil_ = false; /// Vulkan 渲染信息 - VkRenderingInfo rendering_info_{}; + vk::RenderingInfo rendering_info_{}; /// 是否已构建 bool built_ = false; @@ -489,7 +480,7 @@ public: * @return 自身引用 */ render_target_builder& add_color_attachment( - VkImageView image_view, + vk::ImageView image_view, const clear_color& clear_value = clear_color::black(), attachment_load_op load_op = attachment_load_op::clear, attachment_store_op store_op = attachment_store_op::store); @@ -504,8 +495,8 @@ public: * @return 自身引用 */ render_target_builder& add_color_attachment_msaa( - VkImageView image_view, - VkImageView resolve_view, + vk::ImageView image_view, + vk::ImageView resolve_view, const clear_color& clear_value = clear_color::black(), attachment_load_op load_op = attachment_load_op::clear, attachment_store_op store_op = attachment_store_op::store); @@ -519,7 +510,7 @@ public: * @return 自身引用 */ render_target_builder& set_depth_attachment( - VkImageView image_view, + vk::ImageView image_view, f32 clear_value = 1.0f, attachment_load_op load_op = attachment_load_op::clear, attachment_store_op store_op = attachment_store_op::store); @@ -532,7 +523,7 @@ public: * @return 自身引用 */ render_target_builder& set_depth_stencil_attachment( - VkImageView image_view, + vk::ImageView image_view, f32 clear_depth = 1.0f, u32 clear_stencil = 0); @@ -562,8 +553,8 @@ private: * @return 渲染目标 */ [[nodiscard]] render_target make_color_render_target( - VkImageView image_view, - VkExtent2D extent, + vk::ImageView image_view, + vk::Extent2D extent, const clear_color& clear_value = clear_color::black()); /** @@ -576,9 +567,9 @@ private: * @return 渲染目标 */ [[nodiscard]] render_target make_color_depth_render_target( - VkImageView color_view, - VkImageView depth_view, - VkExtent2D extent, + vk::ImageView color_view, + vk::ImageView depth_view, + vk::Extent2D extent, const clear_color& clear_value = clear_color::black(), f32 clear_depth = 1.0f); diff --git a/src/render/renderer.cpp b/src/render/renderer.cpp index 7e072b6..788e81c 100644 --- a/src/render/renderer.cpp +++ b/src/render/renderer.cpp @@ -51,11 +51,11 @@ renderer::renderer(renderer&& other) noexcept { other.state_ = render_state::uninitialized; other.window_ = nullptr; - other.surface_ = VK_NULL_HANDLE; + other.surface_ = nullptr; other.allocator_ = VK_NULL_HANDLE; - other.depth_image_ = VK_NULL_HANDLE; - other.depth_allocation_ = VK_NULL_HANDLE; - other.depth_image_view_ = VK_NULL_HANDLE; + other.depth_image_ = nullptr; + other.depth_allocation_ = nullptr; + other.depth_image_view_ = nullptr; } renderer& renderer::operator=(renderer&& other) noexcept { @@ -90,23 +90,23 @@ renderer& renderer::operator=(renderer&& other) noexcept { other.state_ = render_state::uninitialized; other.window_ = nullptr; - other.surface_ = VK_NULL_HANDLE; + other.surface_ = nullptr; other.allocator_ = VK_NULL_HANDLE; - other.depth_image_ = VK_NULL_HANDLE; - other.depth_allocation_ = VK_NULL_HANDLE; - other.depth_image_view_ = VK_NULL_HANDLE; + other.depth_image_ = nullptr; + other.depth_allocation_ = nullptr; + other.depth_image_view_ = nullptr; } return *this; } bool renderer::initialize(SDL_Window* window) { if (state_ != render_state::uninitialized) { - LOG_WARN("Renderer already initialized"); + MILAI_LOG_WARN("Renderer already initialized"); return true; } if (!window) { - LOG_ERROR("Invalid window pointer"); + MILAI_LOG_ERROR("Invalid window pointer"); return false; } @@ -124,61 +124,53 @@ bool renderer::initialize(SDL_Window* window) { instance_config.app_version = config_.app_version; instance_config.enable_validation = config_.enable_validation; - // 获取 SDL 所需的 Vulkan 扩展 - u32 sdl_extension_count = 0; - const char* const* sdl_extensions = SDL_Vulkan_GetInstanceExtensions(&sdl_extension_count); - if (sdl_extensions) { - for (u32 i = 0; i < sdl_extension_count; ++i) { - instance_config.required_extensions.push_back(sdl_extensions[i]); - } - } + // SDL 扩展由 vulkan_instance 自动获取,无需手动添加 - instance_ = std::make_unique(instance_config); + instance_ = std::make_shared(instance_config); if (!instance_->is_valid()) { - LOG_ERROR("Failed to create Vulkan instance"); + MILAI_LOG_ERROR("Failed to create Vulkan instance"); return false; } // 2. 创建表面 if (!create_surface(window)) { - LOG_ERROR("Failed to create Vulkan surface"); + MILAI_LOG_ERROR("Failed to create Vulkan surface"); return false; } // 3. 创建设备 vulkan_device_config device_config{}; - device_config.required_extensions.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME); - device_config.enable_dynamic_rendering = true; - device_config.enable_synchronization2 = true; - device_config.surface = surface_; + device_config.extra_extensions.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME); + device_config.require_dynamic_rendering = true; + device_config.require_synchronization2 = true; - device_ = std::make_shared(instance_, device_config); + device_ = std::make_shared(instance_, surface_, device_config); if (!device_->is_valid()) { - LOG_ERROR("Failed to create Vulkan device"); + MILAI_LOG_ERROR("Failed to create Vulkan device"); return false; } // 4. 创建 VMA 分配器 if (!create_allocator()) { - LOG_ERROR("Failed to create VMA allocator"); + MILAI_LOG_ERROR("Failed to create VMA allocator"); return false; } // 5. 创建交换链 if (!create_swapchain(config_.viewport_width, config_.viewport_height)) { - LOG_ERROR("Failed to create swapchain"); + MILAI_LOG_ERROR("Failed to create swapchain"); return false; } // 6. 创建深度资源 if (!create_depth_resources()) { - LOG_ERROR("Failed to create depth resources"); + MILAI_LOG_ERROR("Failed to create depth resources"); return false; } // 7. 创建命令池 if (!create_command_pools()) { - LOG_ERROR("Failed to create command pools"); + MILAI_LOG_ERROR("Failed to create command pools"); return false; } @@ -188,7 +180,7 @@ bool renderer::initialize(SDL_Window* window) { frame_sync_ = std::make_unique(device_, swapchain_, sync_config); if (!frame_sync_->is_valid()) { - LOG_ERROR("Failed to create frame sync"); + MILAI_LOG_ERROR("Failed to create frame sync"); return false; } @@ -200,16 +192,16 @@ bool renderer::initialize(SDL_Window* window) { batch_renderer_ = std::make_unique(device_, allocator_, batch_config); if (!batch_renderer_->initialize(swapchain_->get_format(), depth_format_)) { - LOG_WARN("Batch renderer initialization incomplete (needs shaders)"); + MILAI_LOG_WARN("Batch renderer initialization incomplete (needs shaders)"); // 不视为致命错误,因为着色器可能稍后加载 } state_ = render_state::initialized; - LOG_INFO("Renderer initialized successfully"); - LOG_INFO(" - Vulkan Instance: {}", (void*)instance_->get_instance()); - LOG_INFO(" - Physical Device: {}", device_->get_physical_device_info().device_name); - LOG_INFO(" - Swapchain: {}x{}", swapchain_->get_extent().width, swapchain_->get_extent().height); - LOG_INFO(" - Frames in Flight: {}", config_.frames_in_flight); + MILAI_LOG_INFO("Renderer initialized successfully"); + MILAI_LOG_INFO(" - Vulkan Instance: {}", (void*)static_cast(instance_->get_instance())); + MILAI_LOG_INFO(" - Physical Device: {}", device_->get_device_name()); + MILAI_LOG_INFO(" - Swapchain: {}x{}", swapchain_->get_extent().width, swapchain_->get_extent().height); + MILAI_LOG_INFO(" - Frames in Flight: {}", config_.frames_in_flight); return true; } @@ -228,21 +220,21 @@ void renderer::shutdown() { destroy_resources(); state_ = render_state::uninitialized; - LOG_INFO("Renderer shutdown"); + MILAI_LOG_INFO("Renderer shutdown"); } bool renderer::begin_frame() { if (state_ != render_state::initialized) { if (state_ == render_state::frame_in_progress) { - LOG_WARN("Frame already in progress"); + MILAI_LOG_WARN("Frame already in progress"); return true; } - LOG_ERROR("Cannot begin frame: renderer not in valid state"); + MILAI_LOG_ERROR("Cannot begin frame: renderer not in valid state"); return false; } // 检查窗口是否最小化 - u32 window_flags = SDL_GetWindowFlags(window_); + const auto window_flags = SDL_GetWindowFlags(window_); window_minimized_ = (window_flags & SDL_WINDOW_MINIMIZED) != 0; if (window_minimized_) { @@ -262,7 +254,7 @@ bool renderer::begin_frame() { SDL_GetWindowSize(window_, &width, &height); if (!recreate_swapchain(static_cast(width), static_cast(height))) { - LOG_ERROR("Failed to recreate swapchain"); + MILAI_LOG_ERROR("Failed to recreate swapchain"); state_ = render_state::error; return false; } @@ -270,12 +262,12 @@ bool renderer::begin_frame() { // 重试 auto [retry_result, retry_index] = frame_sync_->begin_frame(); if (retry_result != frame_begin_result::success) { - LOG_ERROR("Failed to begin frame after swapchain recreation"); + MILAI_LOG_ERROR("Failed to begin frame after swapchain recreation"); return false; } image_index = retry_index; } else if (result != frame_begin_result::success) { - LOG_ERROR("Failed to begin frame"); + MILAI_LOG_ERROR("Failed to begin frame"); return false; } @@ -283,15 +275,14 @@ bool renderer::begin_frame() { current_image_index_ = image_index; // 重置并开始命令缓冲录制 - VkCommandBuffer cmd_buffer = frame_sync_->get_current_command_buffer(); + vk::CommandBuffer cmd_buffer = frame_sync_->get_current_command_buffer(); - VkCommandBufferBeginInfo begin_info{}; - begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; - begin_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; + vk::CommandBufferBeginInfo begin_info{}; + begin_info.flags = vk::CommandBufferUsageFlagBits::eOneTimeSubmit; - VkResult vk_result = vkBeginCommandBuffer(cmd_buffer, &begin_info); - if (vk_result != VK_SUCCESS) { - LOG_ERROR("Failed to begin command buffer: {}", vk_result_to_string(vk_result)); + auto vk_result = cmd_buffer.begin(&begin_info); + if (vk_result != vk::Result::eSuccess) { + MILAI_LOG_ERROR("Failed to begin command buffer: {}", vk_result_to_string(vk_result)); return false; } @@ -308,7 +299,7 @@ bool renderer::begin_frame() { bool renderer::end_frame() { if (state_ != render_state::frame_in_progress && state_ != render_state::rendering_in_progress) { - LOG_ERROR("Cannot end frame: frame not in progress"); + MILAI_LOG_ERROR("Cannot end frame: frame not in progress"); return false; } @@ -317,12 +308,12 @@ bool renderer::end_frame() { end_rendering(); } - VkCommandBuffer cmd_buffer = frame_sync_->get_current_command_buffer(); + vk::CommandBuffer cmd_buffer = frame_sync_->get_current_command_buffer(); // 结束命令缓冲录制 - VkResult vk_result = vkEndCommandBuffer(cmd_buffer); - if (vk_result != VK_SUCCESS) { - LOG_ERROR("Failed to end command buffer: {}", vk_result_to_string(vk_result)); + auto vk_result = cmd_buffer.end(); + if (vk_result != vk::Result::eSuccess) { + MILAI_LOG_ERROR("Failed to end command buffer: {}", vk_result_to_string(vk_result)); return false; } @@ -333,7 +324,7 @@ bool renderer::end_frame() { result == frame_end_result::swapchain_suboptimal) { swapchain_needs_recreation_ = true; } else if (result != frame_end_result::success) { - LOG_ERROR("Failed to end frame"); + MILAI_LOG_ERROR("Failed to end frame"); return false; } @@ -364,26 +355,26 @@ bool renderer::end_frame() { void renderer::begin_rendering(const render_target& target) { if (state_ != render_state::frame_in_progress) { - LOG_ERROR("Cannot begin rendering: frame not in progress"); + MILAI_LOG_ERROR("Cannot begin rendering: frame not in progress"); return; } - VkCommandBuffer cmd_buffer = frame_sync_->get_current_command_buffer(); + vk::CommandBuffer cmd_buffer = frame_sync_->get_current_command_buffer(); // 转换交换链图像布局到颜色附件 - VkImage swapchain_image = swapchain_->get_images()[current_image_index_]; + vk::Image swapchain_image = swapchain_->get_images()[current_image_index_]; transition_image_layout(cmd_buffer, swapchain_image, - VK_IMAGE_LAYOUT_UNDEFINED, - VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); + vk::ImageLayout::eUndefined, + vk::ImageLayout::eColorAttachmentOptimal); // 构建渲染信息 rendering_info render_info(target); // 开始动态渲染 - vkCmdBeginRendering(cmd_buffer, render_info.get_vulkan_rendering_info()); + cmd_buffer.beginRendering(render_info.get_vulkan_rendering_info()); // 设置视口和裁剪 - VkViewport viewport{}; + vk::Viewport viewport{}; viewport.x = 0.0f; viewport.y = 0.0f; viewport.width = static_cast(target.render_area.extent.width); @@ -391,10 +382,10 @@ void renderer::begin_rendering(const render_target& target) { viewport.minDepth = 0.0f; viewport.maxDepth = 1.0f; - vkCmdSetViewport(cmd_buffer, 0, 1, &viewport); + cmd_buffer.setViewport(0, 1, &viewport); - VkRect2D scissor = target.render_area; - vkCmdSetScissor(cmd_buffer, 0, 1, &scissor); + vk::Rect2D scissor = target.render_area; + cmd_buffer.setScissor(0, 1, &scissor); state_ = render_state::rendering_in_progress; } @@ -403,21 +394,21 @@ void renderer::begin_rendering(const clear_color& clear) { // 创建默认渲染目标(使用当前交换链图像) render_attachment color_attachment{}; color_attachment.image_view = swapchain_->get_image_views()[current_image_index_]; - color_attachment.image_layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + color_attachment.image_layout = vk::ImageLayout::eColorAttachmentOptimal; color_attachment.load_op = attachment_load_op::clear; color_attachment.store_op = attachment_store_op::store; color_attachment.clear_value = clear; render_target target; target.color_attachments.push_back(color_attachment); - target.render_area.offset = {0, 0}; + target.render_area.offset = vk::Offset2D{0, 0}; target.render_area.extent = swapchain_->get_extent(); // 添加深度附件(如果有) - if (depth_image_view_ != VK_NULL_HANDLE) { + if (depth_image_view_) { render_attachment depth_attachment{}; depth_attachment.image_view = depth_image_view_; - depth_attachment.image_layout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL; + depth_attachment.image_layout = vk::ImageLayout::eDepthAttachmentOptimal; depth_attachment.load_op = attachment_load_op::clear; depth_attachment.store_op = attachment_store_op::store; depth_attachment.clear_depth_stencil_value = clear_depth_stencil(1.0f, 0); @@ -429,29 +420,29 @@ void renderer::begin_rendering(const clear_color& clear) { void renderer::end_rendering() { if (state_ != render_state::rendering_in_progress) { - LOG_ERROR("Cannot end rendering: not in rendering state"); + MILAI_LOG_ERROR("Cannot end rendering: not in rendering state"); return; } - VkCommandBuffer cmd_buffer = frame_sync_->get_current_command_buffer(); + vk::CommandBuffer cmd_buffer = frame_sync_->get_current_command_buffer(); // 结束动态渲染 - vkCmdEndRendering(cmd_buffer); + cmd_buffer.endRendering(); // 转换交换链图像布局到呈现 - VkImage swapchain_image = swapchain_->get_images()[current_image_index_]; + vk::Image swapchain_image = swapchain_->get_images()[current_image_index_]; transition_image_layout(cmd_buffer, swapchain_image, - VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, - VK_IMAGE_LAYOUT_PRESENT_SRC_KHR); + vk::ImageLayout::eColorAttachmentOptimal, + vk::ImageLayout::ePresentSrcKHR); state_ = render_state::frame_in_progress; } -VkCommandBuffer renderer::get_command_buffer() const { +vk::CommandBuffer renderer::get_command_buffer() const { if (frame_sync_) { return frame_sync_->get_current_command_buffer(); } - return VK_NULL_HANDLE; + return nullptr; } command_buffer* renderer::get_current_command_buffer() { @@ -461,20 +452,19 @@ command_buffer* renderer::get_current_command_buffer() { return nullptr; } -bool renderer::submit(VkCommandBuffer cmd_buffer) { +bool renderer::submit(vk::CommandBuffer cmd_buffer) { // 直接提交到图形队列 - VkSubmitInfo submit_info{}; - submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; + vk::SubmitInfo submit_info{}; submit_info.commandBufferCount = 1; submit_info.pCommandBuffers = &cmd_buffer; - VkResult result = vkQueueSubmit(device_->get_graphics_queue(), 1, &submit_info, VK_NULL_HANDLE); - return result == VK_SUCCESS; + auto result = device_->get_graphics_queue().submit(1, &submit_info, nullptr); + return result == vk::Result::eSuccess; } bool renderer::present() { // 呈现由 end_frame 自动处理 - LOG_WARN("present() called directly; use end_frame() instead"); + MILAI_LOG_WARN("present() called directly; use end_frame() instead"); return true; } @@ -504,40 +494,40 @@ u32 renderer::get_current_image_index() const { return current_image_index_; } -VkExtent2D renderer::get_swapchain_extent() const { - return swapchain_ ? swapchain_->get_extent() : VkExtent2D{0, 0}; +vk::Extent2D renderer::get_swapchain_extent() const { + return swapchain_ ? swapchain_->get_extent() : vk::Extent2D{0, 0}; } -VkFormat renderer::get_swapchain_format() const { - return swapchain_ ? swapchain_->get_format() : VK_FORMAT_UNDEFINED; +vk::Format renderer::get_swapchain_format() const { + return swapchain_ ? swapchain_->get_format() : vk::Format::eUndefined; } -VkInstance renderer::get_vulkan_instance() const { - return instance_ ? instance_->get_instance() : VK_NULL_HANDLE; +vk::Instance renderer::get_vulkan_instance() const { + return instance_ ? instance_->get_instance() : nullptr; } -VkDevice renderer::get_vulkan_device() const { - return device_ ? device_->get_device() : VK_NULL_HANDLE; +vk::Device renderer::get_vulkan_device() const { + return device_ ? device_->get_device() : nullptr; } -VkPhysicalDevice renderer::get_vulkan_physical_device() const { - return device_ ? device_->get_physical_device() : VK_NULL_HANDLE; +vk::PhysicalDevice renderer::get_vulkan_physical_device() const { + return device_ ? device_->get_physical_device() : nullptr; } -VkQueue renderer::get_graphics_queue() const { - return device_ ? device_->get_graphics_queue() : VK_NULL_HANDLE; +vk::Queue renderer::get_graphics_queue() const { + return device_ ? device_->get_graphics_queue() : nullptr; } -VkQueue renderer::get_present_queue() const { - return device_ ? device_->get_present_queue() : VK_NULL_HANDLE; +vk::Queue renderer::get_present_queue() const { + return device_ ? device_->get_present_queue() : nullptr; } void renderer::on_created() { - LOG_DEBUG("Renderer created"); + MILAI_LOG_DEBUG("Renderer created"); } void renderer::on_destroying() { - LOG_DEBUG("Renderer destroying"); + MILAI_LOG_DEBUG("Renderer destroying"); } bool renderer::create_allocator() { @@ -550,51 +540,54 @@ bool renderer::create_allocator() { VkResult result = vmaCreateAllocator(&allocator_info, &allocator_); if (result != VK_SUCCESS) { - LOG_ERROR("Failed to create VMA allocator: {}", vk_result_to_string(result)); + MILAI_LOG_ERROR("Failed to create VMA allocator: {}", vk_result_to_string(static_cast(result))); return false; } - LOG_DEBUG("VMA allocator created"); + MILAI_LOG_DEBUG("VMA allocator created"); return true; } bool renderer::create_surface(SDL_Window* window) { - if (!SDL_Vulkan_CreateSurface(window, instance_->get_instance(), nullptr, &surface_)) { - LOG_ERROR("Failed to create Vulkan surface: {}", SDL_GetError()); + VkSurfaceKHR c_surface = VK_NULL_HANDLE; + if (!SDL_Vulkan_CreateSurface(window, static_cast(instance_->get_instance()), nullptr, &c_surface)) { + MILAI_LOG_ERROR("Failed to create Vulkan surface: {}", SDL_GetError()); return false; } + surface_ = c_surface; - LOG_DEBUG("Vulkan surface created"); + MILAI_LOG_DEBUG("Vulkan surface created"); return true; } bool renderer::create_swapchain(u32 width, u32 height) { swapchain_config swap_config{}; - swap_config.surface = surface_; - swap_config.width = width; - swap_config.height = height; - swap_config.enable_vsync = config_.enable_vsync; + if (config_.enable_vsync) { + swap_config.preferred_present_mode = vk::PresentModeKHR::eFifo; + } else { + swap_config.preferred_present_mode = vk::PresentModeKHR::eMailbox; + } - swapchain_ = std::make_shared(device_, swap_config); + swapchain_ = std::make_shared(device_, surface_, width, height, swap_config); if (!swapchain_->is_valid()) { - LOG_ERROR("Failed to create swapchain"); + MILAI_LOG_ERROR("Failed to create swapchain"); return false; } - LOG_DEBUG("Swapchain created: {}x{}", width, height); + MILAI_LOG_DEBUG("Swapchain created: {}x{}", width, height); return true; } bool renderer::create_command_pools() { // 创建主命令池 command_pool_ = std::make_unique( - device_, - device_->get_queue_family_indices().graphics_family, + device_, + device_->get_graphics_queue_family(), VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT ); if (!command_pool_->is_valid()) { - LOG_ERROR("Failed to create command pool"); + MILAI_LOG_ERROR("Failed to create command pool"); return false; } @@ -603,30 +596,29 @@ bool renderer::create_command_pools() { for (u32 i = 0; i < config_.frames_in_flight; ++i) { command_buffers_[i] = command_pool_->allocate_buffer(); if (!command_buffers_[i] || !command_buffers_[i]->is_valid()) { - LOG_ERROR("Failed to allocate command buffer {}", i); + MILAI_LOG_ERROR("Failed to allocate command buffer {}", i); return false; } } - LOG_DEBUG("Command pools and buffers created"); + MILAI_LOG_DEBUG("Command pools and buffers created"); return true; } bool renderer::create_depth_resources() { // 选择深度格式 - VkFormat candidates[] = {VK_FORMAT_D32_SFLOAT, VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT}; + vk::Format candidates[] = {vk::Format::eD32Sfloat, vk::Format::eD32SfloatS8Uint, vk::Format::eD24UnormS8Uint}; - for (VkFormat format : candidates) { - VkFormatProperties props; - vkGetPhysicalDeviceFormatProperties(device_->get_physical_device(), format, &props); + for (vk::Format format : candidates) { + vk::FormatProperties props = device_->get_physical_device().getFormatProperties(format); - if (props.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) { + if (props.optimalTilingFeatures & vk::FormatFeatureFlagBits::eDepthStencilAttachment) { depth_format_ = format; break; } } - VkExtent2D extent = swapchain_->get_extent(); + vk::Extent2D extent = swapchain_->get_extent(); // 创建深度图像 VkImageCreateInfo image_info{}; @@ -637,7 +629,7 @@ bool renderer::create_depth_resources() { image_info.extent.depth = 1; image_info.mipLevels = 1; image_info.arrayLayers = 1; - image_info.format = depth_format_; + image_info.format = static_cast(depth_format_); image_info.tiling = VK_IMAGE_TILING_OPTIMAL; image_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; image_info.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; @@ -647,63 +639,66 @@ bool renderer::create_depth_resources() { VmaAllocationCreateInfo alloc_info{}; alloc_info.usage = VMA_MEMORY_USAGE_GPU_ONLY; + VkImage depth_image_raw = VK_NULL_HANDLE; VkResult result = vmaCreateImage(allocator_, &image_info, &alloc_info, - &depth_image_, &depth_allocation_, nullptr); + &depth_image_raw, &depth_allocation_, nullptr); if (result != VK_SUCCESS) { - LOG_ERROR("Failed to create depth image: {}", vk_result_to_string(result)); + MILAI_LOG_ERROR("Failed to create depth image: {}", vk_result_to_string(static_cast(result))); return false; } + depth_image_ = depth_image_raw; // 创建深度图像视图 - VkImageViewCreateInfo view_info{}; - view_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; + vk::ImageViewCreateInfo view_info{}; view_info.image = depth_image_; - view_info.viewType = VK_IMAGE_VIEW_TYPE_2D; + view_info.viewType = vk::ImageViewType::e2D; view_info.format = depth_format_; - view_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; + view_info.subresourceRange.aspectMask = vk::ImageAspectFlagBits::eDepth; view_info.subresourceRange.baseMipLevel = 0; view_info.subresourceRange.levelCount = 1; view_info.subresourceRange.baseArrayLayer = 0; view_info.subresourceRange.layerCount = 1; - result = vkCreateImageView(device_->get_device(), &view_info, nullptr, &depth_image_view_); - if (result != VK_SUCCESS) { - LOG_ERROR("Failed to create depth image view: {}", vk_result_to_string(result)); + auto [view_result, image_view] = device_->get_device().createImageView(view_info); + if (view_result != vk::Result::eSuccess) { + MILAI_LOG_ERROR("Failed to create depth image view: {}", vk_result_to_string(view_result)); return false; } + depth_image_view_ = image_view; - LOG_DEBUG("Depth resources created: format={}", static_cast(depth_format_)); + MILAI_LOG_DEBUG("Depth resources created: format={}", static_cast(depth_format_)); return true; } bool renderer::recreate_swapchain(u32 width, u32 height) { - LOG_DEBUG("Recreating swapchain: {}x{}", width, height); + MILAI_LOG_DEBUG("Recreating swapchain: {}x{}", width, height); // 等待设备空闲 device_->wait_idle(); // 销毁旧的深度资源 - if (depth_image_view_ != VK_NULL_HANDLE) { - vkDestroyImageView(device_->get_device(), depth_image_view_, nullptr); - depth_image_view_ = VK_NULL_HANDLE; + if (depth_image_view_) { + device_->get_device().destroyImageView(depth_image_view_); + depth_image_view_ = nullptr; } - if (depth_image_ != VK_NULL_HANDLE) { - vmaDestroyImage(allocator_, depth_image_, depth_allocation_); - depth_image_ = VK_NULL_HANDLE; - depth_allocation_ = VK_NULL_HANDLE; + if (depth_image_) { + vmaDestroyImage(allocator_, static_cast(depth_image_), depth_allocation_); + depth_image_ = nullptr; + depth_allocation_ = nullptr; } // 重建交换链 swapchain_config swap_config{}; - swap_config.surface = surface_; - swap_config.width = width; - swap_config.height = height; - swap_config.enable_vsync = config_.enable_vsync; - swap_config.old_swapchain = swapchain_ ? swapchain_->get_swapchain() : VK_NULL_HANDLE; + if (config_.enable_vsync) { + swap_config.preferred_present_mode = vk::PresentModeKHR::eFifo; + } else { + swap_config.preferred_present_mode = vk::PresentModeKHR::eMailbox; + } + swap_config.old_swapchain = swapchain_ ? swapchain_->get_swapchain() : nullptr; - auto new_swapchain = std::make_shared(device_, swap_config); + auto new_swapchain = std::make_shared(device_, surface_, width, height, swap_config); if (!new_swapchain->is_valid()) { - LOG_ERROR("Failed to recreate swapchain"); + MILAI_LOG_ERROR("Failed to recreate swapchain"); return false; } @@ -712,7 +707,7 @@ bool renderer::recreate_swapchain(u32 width, u32 height) { // 重建深度资源 if (!create_depth_resources()) { - LOG_ERROR("Failed to recreate depth resources"); + MILAI_LOG_ERROR("Failed to recreate depth resources"); return false; } @@ -732,7 +727,7 @@ bool renderer::recreate_swapchain(u32 width, u32 height) { on_swapchain_recreated_(); } - LOG_INFO("Swapchain recreated: {}x{}", width, height); + MILAI_LOG_INFO("Swapchain recreated: {}x{}", width, height); return true; } @@ -748,14 +743,14 @@ void renderer::destroy_resources() { frame_sync_.reset(); // 销毁深度资源 - if (depth_image_view_ != VK_NULL_HANDLE && device_) { - vkDestroyImageView(device_->get_device(), depth_image_view_, nullptr); - depth_image_view_ = VK_NULL_HANDLE; + if (depth_image_view_ && device_) { + device_->get_device().destroyImageView(depth_image_view_); + depth_image_view_ = nullptr; } - if (depth_image_ != VK_NULL_HANDLE && allocator_) { - vmaDestroyImage(allocator_, depth_image_, depth_allocation_); - depth_image_ = VK_NULL_HANDLE; - depth_allocation_ = VK_NULL_HANDLE; + if (depth_image_ && allocator_) { + vmaDestroyImage(allocator_, static_cast(depth_image_), depth_allocation_); + depth_image_ = nullptr; + depth_allocation_ = nullptr; } // 销毁交换链 @@ -768,9 +763,9 @@ void renderer::destroy_resources() { } // 销毁表面 - if (surface_ != VK_NULL_HANDLE && instance_) { - vkDestroySurfaceKHR(instance_->get_instance(), surface_, nullptr); - surface_ = VK_NULL_HANDLE; + if (surface_ && instance_) { + instance_->get_instance().destroySurfaceKHR(surface_); + surface_ = nullptr; } // 销毁设备 @@ -782,49 +777,47 @@ void renderer::destroy_resources() { window_ = nullptr; } -void renderer::transition_image_layout(VkCommandBuffer cmd_buffer, VkImage image, - VkImageLayout old_layout, VkImageLayout new_layout) +void renderer::transition_image_layout(vk::CommandBuffer cmd_buffer, vk::Image image, + vk::ImageLayout old_layout, vk::ImageLayout new_layout) { - VkImageMemoryBarrier2 barrier{}; - barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2; + vk::ImageMemoryBarrier2 barrier{}; barrier.oldLayout = old_layout; barrier.newLayout = new_layout; barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; barrier.image = image; - barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + barrier.subresourceRange.aspectMask = vk::ImageAspectFlagBits::eColor; barrier.subresourceRange.baseMipLevel = 0; barrier.subresourceRange.levelCount = 1; barrier.subresourceRange.baseArrayLayer = 0; barrier.subresourceRange.layerCount = 1; // 设置源和目标阶段/访问掩码 - if (old_layout == VK_IMAGE_LAYOUT_UNDEFINED && - new_layout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) { - barrier.srcStageMask = VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT; - barrier.srcAccessMask = VK_ACCESS_2_NONE; - barrier.dstStageMask = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT; - barrier.dstAccessMask = VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT; - } else if (old_layout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL && - new_layout == VK_IMAGE_LAYOUT_PRESENT_SRC_KHR) { - barrier.srcStageMask = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT; - barrier.srcAccessMask = VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT; - barrier.dstStageMask = VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT; - barrier.dstAccessMask = VK_ACCESS_2_NONE; + if (old_layout == vk::ImageLayout::eUndefined && + new_layout == vk::ImageLayout::eColorAttachmentOptimal) { + barrier.srcStageMask = vk::PipelineStageFlagBits2::eTopOfPipe; + barrier.srcAccessMask = vk::AccessFlagBits2::eNone; + barrier.dstStageMask = vk::PipelineStageFlagBits2::eColorAttachmentOutput; + barrier.dstAccessMask = vk::AccessFlagBits2::eColorAttachmentWrite; + } else if (old_layout == vk::ImageLayout::eColorAttachmentOptimal && + new_layout == vk::ImageLayout::ePresentSrcKHR) { + barrier.srcStageMask = vk::PipelineStageFlagBits2::eColorAttachmentOutput; + barrier.srcAccessMask = vk::AccessFlagBits2::eColorAttachmentWrite; + barrier.dstStageMask = vk::PipelineStageFlagBits2::eBottomOfPipe; + barrier.dstAccessMask = vk::AccessFlagBits2::eNone; } else { // 通用转换 - barrier.srcStageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT; - barrier.srcAccessMask = VK_ACCESS_2_MEMORY_WRITE_BIT; - barrier.dstStageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT; - barrier.dstAccessMask = VK_ACCESS_2_MEMORY_READ_BIT | VK_ACCESS_2_MEMORY_WRITE_BIT; + barrier.srcStageMask = vk::PipelineStageFlagBits2::eAllCommands; + barrier.srcAccessMask = vk::AccessFlagBits2::eMemoryWrite; + barrier.dstStageMask = vk::PipelineStageFlagBits2::eAllCommands; + barrier.dstAccessMask = vk::AccessFlagBits2::eMemoryRead | vk::AccessFlagBits2::eMemoryWrite; } - VkDependencyInfo dependency_info{}; - dependency_info.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO; + vk::DependencyInfo dependency_info{}; dependency_info.imageMemoryBarrierCount = 1; dependency_info.pImageMemoryBarriers = &barrier; - vkCmdPipelineBarrier2(cmd_buffer, &dependency_info); + cmd_buffer.pipelineBarrier2(&dependency_info); } } // namespace milai \ No newline at end of file diff --git a/src/render/renderer.hpp b/src/render/renderer.hpp index 244d12b..9678e32 100644 --- a/src/render/renderer.hpp +++ b/src/render/renderer.hpp @@ -22,8 +22,7 @@ #include "object.hpp" #include "types.hpp" -#include -#include +#include #include #include #include @@ -154,7 +153,7 @@ public: * @brief 获取当前命令缓冲 * @return 当前命令缓冲 */ - [[nodiscard]] VkCommandBuffer get_command_buffer() const; + [[nodiscard]] vk::CommandBuffer get_command_buffer() const; /** * @brief 获取当前帧的命令缓冲封装 @@ -173,7 +172,7 @@ public: * @param cmd_buffer 命令缓冲 * @return 是否成功 */ - [[nodiscard]] bool submit(VkCommandBuffer cmd_buffer); + [[nodiscard]] bool submit(vk::CommandBuffer cmd_buffer); /** * @brief 呈现当前帧 @@ -210,13 +209,13 @@ public: * @brief 获取交换链尺寸 * @return 交换链尺寸 */ - [[nodiscard]] VkExtent2D get_swapchain_extent() const; + [[nodiscard]] vk::Extent2D get_swapchain_extent() const; /** * @brief 获取交换链格式 * @return 交换链格式 */ - [[nodiscard]] VkFormat get_swapchain_format() const; + [[nodiscard]] vk::Format get_swapchain_format() const; /** * @brief 获取渲染状态 @@ -283,31 +282,31 @@ public: * @brief 获取 VkInstance * @return VkInstance 句柄 */ - [[nodiscard]] VkInstance get_vulkan_instance() const; + [[nodiscard]] vk::Instance get_vulkan_instance() const; /** - * @brief 获取 VkDevice - * @return VkDevice 句柄 + * @brief 获取 vk::Device + * @return vk::Device 句柄 */ - [[nodiscard]] VkDevice get_vulkan_device() const; + [[nodiscard]] vk::Device get_vulkan_device() const; /** - * @brief 获取 VkPhysicalDevice - * @return VkPhysicalDevice 句柄 + * @brief 获取 vk::PhysicalDevice + * @return vk::PhysicalDevice 句柄 */ - [[nodiscard]] VkPhysicalDevice get_vulkan_physical_device() const; + [[nodiscard]] vk::PhysicalDevice get_vulkan_physical_device() const; /** * @brief 获取图形队列 * @return 图形队列 */ - [[nodiscard]] VkQueue get_graphics_queue() const; + [[nodiscard]] vk::Queue get_graphics_queue() const; /** * @brief 获取呈现队列 * @return 呈现队列 */ - [[nodiscard]] VkQueue get_present_queue() const; + [[nodiscard]] vk::Queue get_present_queue() const; // ============================================================================================= // 回调设置 @@ -412,8 +411,8 @@ private: * @param old_layout 旧布局 * @param new_layout 新布局 */ - void transition_image_layout(VkCommandBuffer cmd_buffer, VkImage image, - VkImageLayout old_layout, VkImageLayout new_layout); + void transition_image_layout(vk::CommandBuffer cmd_buffer, vk::Image image, + vk::ImageLayout old_layout, vk::ImageLayout new_layout); /// 配置 renderer_config config_; @@ -425,13 +424,13 @@ private: SDL_Window* window_ = nullptr; /// Vulkan 实例 - std::unique_ptr instance_; + std::shared_ptr instance_; /// Vulkan 设备 std::shared_ptr device_; /// 表面 - VkSurfaceKHR surface_ = VK_NULL_HANDLE; + vk::SurfaceKHR surface_; /// 交换链 std::shared_ptr swapchain_; @@ -452,10 +451,10 @@ private: std::unique_ptr batch_renderer_; /// 深度图像 - VkImage depth_image_ = VK_NULL_HANDLE; - VmaAllocation depth_allocation_ = VK_NULL_HANDLE; - VkImageView depth_image_view_ = VK_NULL_HANDLE; - VkFormat depth_format_ = VK_FORMAT_D32_SFLOAT; + vk::Image depth_image_; + VmaAllocation depth_allocation_ = nullptr; + vk::ImageView depth_image_view_; + vk::Format depth_format_ = vk::Format::eD32Sfloat; /// 当前帧索引 u32 current_frame_index_ = 0; diff --git a/src/render/swapchain.cpp b/src/render/swapchain.cpp index 4e2780e..2aeed9c 100644 --- a/src/render/swapchain.cpp +++ b/src/render/swapchain.cpp @@ -17,7 +17,7 @@ namespace milai { // ================================================================================================ swapchain::swapchain(std::shared_ptr device, - VkSurfaceKHR surface, + vk::SurfaceKHR surface, u32 width, u32 height, const swapchain_config& config) : device_(std::move(device)) @@ -26,7 +26,7 @@ swapchain::swapchain(std::shared_ptr device, { auto result = create_swapchain(width, height, config); if (!result.has_value()) { - LOG_ERROR("Failed to create swapchain: {}", result.error().message); + MILAI_LOG_ERROR("Failed to create swapchain: {}", result.error().message); } } @@ -46,8 +46,8 @@ swapchain::swapchain(swapchain&& other) noexcept , config_(other.config_) , needs_recreate_(other.needs_recreate_) { - other.surface_ = VK_NULL_HANDLE; - other.swapchain_ = VK_NULL_HANDLE; + other.surface_ = nullptr; + other.swapchain_ = nullptr; } swapchain& swapchain::operator=(swapchain&& other) noexcept { @@ -65,8 +65,8 @@ swapchain& swapchain::operator=(swapchain&& other) noexcept { config_ = other.config_; needs_recreate_ = other.needs_recreate_; - other.surface_ = VK_NULL_HANDLE; - other.swapchain_ = VK_NULL_HANDLE; + other.surface_ = nullptr; + other.swapchain_ = nullptr; } return *this; } @@ -76,12 +76,12 @@ swapchain& swapchain::operator=(swapchain&& other) noexcept { // ================================================================================================ void swapchain::on_created() { - LOG_INFO("Swapchain created: {}x{}, {} images", + MILAI_LOG_INFO("Swapchain created: {}x{}, {} images", extent_.width, extent_.height, images_.size()); } void swapchain::on_destroying() { - LOG_INFO("Swapchain destroying"); + MILAI_LOG_INFO("Swapchain destroying"); } // ================================================================================================ @@ -106,20 +106,19 @@ void_result swapchain::create_swapchain(u32 width, u32 height, const swapchain_c extent_ = support.choose_extent(width, height); // 选择图像数量 - u32 image_count = config.preferred_image_count > 0 - ? config.preferred_image_count + u32 image_count = config.preferred_image_count > 0 + ? config.preferred_image_count : support.choose_image_count(3); // 默认尝试三重缓冲 // 创建交换链 - VkSwapchainCreateInfoKHR create_info{}; - create_info.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; - create_info.surface = surface_; - create_info.minImageCount = image_count; - create_info.imageFormat = format_.format; - create_info.imageColorSpace = format_.colorSpace; - create_info.imageExtent = extent_; - create_info.imageArrayLayers = 1; - create_info.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; + vk::SwapchainCreateInfoKHR create_info{}; + create_info.setSurface(surface_) + .setMinImageCount(image_count) + .setImageFormat(format_.format) + .setImageColorSpace(format_.colorSpace) + .setImageExtent(extent_) + .setImageArrayLayers(1) + .setImageUsage(vk::ImageUsageFlagBits::eColorAttachment | vk::ImageUsageFlagBits::eTransferDst); // 设置队列族共享模式 const auto& queue_families = device_->get_queue_family_indices(); @@ -129,32 +128,32 @@ void_result swapchain::create_swapchain(u32 width, u32 height, const swapchain_c std::array queue_family_indices = {graphics_family, present_family}; if (graphics_family != present_family) { - create_info.imageSharingMode = VK_SHARING_MODE_CONCURRENT; - create_info.queueFamilyIndexCount = 2; - create_info.pQueueFamilyIndices = queue_family_indices.data(); + create_info.setImageSharingMode(vk::SharingMode::eConcurrent) + .setQueueFamilyIndices(queue_family_indices); } else { - create_info.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; - create_info.queueFamilyIndexCount = 0; - create_info.pQueueFamilyIndices = nullptr; + create_info.setImageSharingMode(vk::SharingMode::eExclusive); } - create_info.preTransform = support.capabilities.currentTransform; - create_info.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; - create_info.presentMode = present_mode_; - create_info.clipped = VK_TRUE; - create_info.oldSwapchain = config.old_swapchain; + create_info.setPreTransform(support.capabilities.currentTransform) + .setCompositeAlpha(vk::CompositeAlphaFlagBitsKHR::eOpaque) + .setPresentMode(present_mode_) + .setClipped(VK_TRUE) + .setOldSwapchain(config.old_swapchain); - VkResult result = vkCreateSwapchainKHR(device_->get_device(), &create_info, nullptr, &swapchain_); - if (result != VK_SUCCESS) { + auto [result, sc] = device_->get_device().createSwapchainKHR(create_info); + if (result != vk::Result::eSuccess) { return make_void_error(error_code::swapchain_creation_failed, - std::string("Failed to create swapchain: ") + std::string(vk_result_to_string(result))); + std::string("Failed to create swapchain: ") + vk::to_string(result)); } + swapchain_ = sc; // 获取交换链图像 - u32 actual_image_count = 0; - vkGetSwapchainImagesKHR(device_->get_device(), swapchain_, &actual_image_count, nullptr); - images_.resize(actual_image_count); - vkGetSwapchainImagesKHR(device_->get_device(), swapchain_, &actual_image_count, images_.data()); + auto [res_imgs, imgs] = device_->get_device().getSwapchainImagesKHR(swapchain_); + if (res_imgs != vk::Result::eSuccess) { + return make_void_error(error_code::swapchain_creation_failed, + std::string("Failed to get swapchain images: ") + vk::to_string(res_imgs)); + } + images_ = imgs; // 创建图像视图 auto view_result = create_image_views(); @@ -162,11 +161,11 @@ void_result swapchain::create_swapchain(u32 width, u32 height, const swapchain_c return view_result; } - LOG_INFO("Swapchain created:"); - LOG_INFO(" Format: {}", static_cast(format_.format)); - LOG_INFO(" Present mode: {}", static_cast(present_mode_)); - LOG_INFO(" Extent: {}x{}", extent_.width, extent_.height); - LOG_INFO(" Image count: {}", images_.size()); + MILAI_LOG_INFO("Swapchain created:"); + MILAI_LOG_INFO(" Format: {}", static_cast(format_.format)); + MILAI_LOG_INFO(" Present mode: {}", static_cast(present_mode_)); + MILAI_LOG_INFO(" Extent: {}x{}", extent_.width, extent_.height); + MILAI_LOG_INFO(" Image count: {}", images_.size()); needs_recreate_ = false; return make_success(); @@ -176,34 +175,25 @@ void_result swapchain::create_image_views() { image_views_.resize(images_.size()); for (size_t i = 0; i < images_.size(); ++i) { - VkImageViewCreateInfo create_info{}; - create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; - create_info.image = images_[i]; - create_info.viewType = VK_IMAGE_VIEW_TYPE_2D; - create_info.format = format_.format; - create_info.components.r = VK_COMPONENT_SWIZZLE_IDENTITY; - create_info.components.g = VK_COMPONENT_SWIZZLE_IDENTITY; - create_info.components.b = VK_COMPONENT_SWIZZLE_IDENTITY; - create_info.components.a = VK_COMPONENT_SWIZZLE_IDENTITY; - create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - create_info.subresourceRange.baseMipLevel = 0; - create_info.subresourceRange.levelCount = 1; - create_info.subresourceRange.baseArrayLayer = 0; - create_info.subresourceRange.layerCount = 1; + vk::ImageViewCreateInfo create_info{}; + create_info.setImage(images_[i]) + .setViewType(vk::ImageViewType::e2D) + .setFormat(format_.format) + .setComponents({vk::ComponentSwizzle::eIdentity, vk::ComponentSwizzle::eIdentity, vk::ComponentSwizzle::eIdentity, vk::ComponentSwizzle::eIdentity}) + .setSubresourceRange({vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1}); - VkResult result = vkCreateImageView(device_->get_device(), &create_info, nullptr, - &image_views_[i]); - if (result != VK_SUCCESS) { + auto [result, view] = device_->get_device().createImageView(create_info); + if (result != vk::Result::eSuccess) { // 清理已创建的视图 for (size_t j = 0; j < i; ++j) { - vkDestroyImageView(device_->get_device(), image_views_[j], nullptr); + device_->get_device().destroyImageView(image_views_[j]); } image_views_.clear(); return make_void_error(error_code::swapchain_creation_failed, - std::string("Failed to create image view: ") + - std::string(vk_result_to_string(result))); + std::string("Failed to create image view: ") + vk::to_string(result)); } + image_views_[i] = view; } return make_success(); @@ -212,17 +202,17 @@ void_result swapchain::create_image_views() { void swapchain::cleanup() { if (device_ && device_->is_valid()) { // 销毁图像视图 - for (VkImageView view : image_views_) { - if (view != VK_NULL_HANDLE) { - vkDestroyImageView(device_->get_device(), view, nullptr); + for (auto& view : image_views_) { + if (view) { + device_->get_device().destroyImageView(view); } } image_views_.clear(); // 销毁交换链 - if (swapchain_ != VK_NULL_HANDLE) { - vkDestroySwapchainKHR(device_->get_device(), swapchain_, nullptr); - swapchain_ = VK_NULL_HANDLE; + if (swapchain_) { + device_->get_device().destroySwapchainKHR(swapchain_); + swapchain_ = nullptr; } } @@ -232,31 +222,28 @@ void swapchain::cleanup() { swapchain_support_details swapchain::query_support() const { swapchain_support_details details; - if (device_ == nullptr || surface_ == VK_NULL_HANDLE) { + if (device_ == nullptr || !surface_) { return details; } - VkPhysicalDevice physical_device = device_->get_physical_device(); + vk::PhysicalDevice physical_device = device_->get_physical_device(); // 获取表面能力 - vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physical_device, surface_, &details.capabilities); + auto [res_cap, caps] = physical_device.getSurfaceCapabilitiesKHR(surface_); + if (res_cap == vk::Result::eSuccess) { + details.capabilities = caps; + } // 获取表面格式 - u32 format_count = 0; - vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device, surface_, &format_count, nullptr); - if (format_count > 0) { - details.formats.resize(format_count); - vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device, surface_, &format_count, - details.formats.data()); + auto [res_fmt, formats] = physical_device.getSurfaceFormatsKHR(surface_); + if (res_fmt == vk::Result::eSuccess) { + details.formats = formats; } // 获取呈现模式 - u32 present_mode_count = 0; - vkGetPhysicalDeviceSurfacePresentModesKHR(physical_device, surface_, &present_mode_count, nullptr); - if (present_mode_count > 0) { - details.present_modes.resize(present_mode_count); - vkGetPhysicalDeviceSurfacePresentModesKHR(physical_device, surface_, &present_mode_count, - details.present_modes.data()); + auto [res_mode, modes] = physical_device.getSurfacePresentModesKHR(surface_); + if (res_mode == vk::Result::eSuccess) { + details.present_modes = modes; } return details; @@ -267,70 +254,64 @@ swapchain_support_details swapchain::query_support() const { // ================================================================================================ std::pair swapchain::acquire_next_image( - VkSemaphore semaphore, - VkFence fence, + vk::Semaphore semaphore, + vk::Fence fence, u64 timeout) { - u32 image_index = 0; - VkResult result = vkAcquireNextImageKHR(device_->get_device(), swapchain_, timeout, - semaphore, fence, &image_index); + auto [result, image_index] = device_->get_device().acquireNextImageKHR(swapchain_, timeout, semaphore, fence); switch (result) { - case VK_SUCCESS: + case vk::Result::eSuccess: return {acquire_result::success, image_index}; - case VK_SUBOPTIMAL_KHR: + case vk::Result::eSuboptimalKHR: needs_recreate_ = true; return {acquire_result::suboptimal, image_index}; - case VK_ERROR_OUT_OF_DATE_KHR: + case vk::Result::eErrorOutOfDateKHR: needs_recreate_ = true; return {acquire_result::out_of_date, 0}; - case VK_TIMEOUT: + case vk::Result::eTimeout: return {acquire_result::timeout, 0}; - case VK_NOT_READY: + case vk::Result::eNotReady: return {acquire_result::not_ready, 0}; default: - LOG_ERROR("Failed to acquire swapchain image: {}", vk_result_to_string(result)); + MILAI_LOG_ERROR("Failed to acquire swapchain image: {}", vk::to_string(result)); return {acquire_result::error, 0}; } } -present_result swapchain::present(u32 image_index, std::span wait_semaphores) { - VkPresentInfoKHR present_info{}; - present_info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; - present_info.waitSemaphoreCount = static_cast(wait_semaphores.size()); - present_info.pWaitSemaphores = wait_semaphores.data(); - present_info.swapchainCount = 1; - present_info.pSwapchains = &swapchain_; - present_info.pImageIndices = &image_index; - present_info.pResults = nullptr; +present_result swapchain::present(u32 image_index, std::span wait_semaphores) { + vk::PresentInfoKHR present_info{}; + present_info.setWaitSemaphores(wait_semaphores) + .setSwapchains(swapchain_) + .setImageIndices(image_index); - VkResult result = vkQueuePresentKHR(device_->get_present_queue(), &present_info); + const auto result = device_->get_present_queue().presentKHR(present_info); switch (result) { - case VK_SUCCESS: + case vk::Result::eSuccess: return present_result::success; - case VK_SUBOPTIMAL_KHR: + case vk::Result::eSuboptimalKHR: needs_recreate_ = true; return present_result::suboptimal; - case VK_ERROR_OUT_OF_DATE_KHR: + case vk::Result::eErrorOutOfDateKHR: needs_recreate_ = true; return present_result::out_of_date; default: - LOG_ERROR("Failed to present: {}", vk_result_to_string(result)); + MILAI_LOG_ERROR("Failed to present: {}", vk::to_string(result)); return present_result::error; } } -present_result swapchain::present(u32 image_index, VkSemaphore wait_semaphore) { - std::array semaphores = {wait_semaphore}; +present_result swapchain::present(u32 image_index, vk::Semaphore wait_semaphore) { + std::array semaphores = {wait_semaphore}; return present(image_index, semaphores); } @@ -343,13 +324,13 @@ void_result swapchain::recreate(u32 width, u32 height) { device_->wait_idle(); // 保存旧的交换链 - VkSwapchainKHR old_swapchain = swapchain_; - swapchain_ = VK_NULL_HANDLE; + vk::SwapchainKHR old_swapchain = swapchain_; + swapchain_ = nullptr; // 清理图像视图(图像由交换链管理,不需要手动清理) - for (VkImageView view : image_views_) { - if (view != VK_NULL_HANDLE) { - vkDestroyImageView(device_->get_device(), view, nullptr); + for (auto& view : image_views_) { + if (view) { + device_->get_device().destroyImageView(view); } } image_views_.clear(); @@ -363,8 +344,8 @@ void_result swapchain::recreate(u32 width, u32 height) { auto result = create_swapchain(width, height, new_config); // 销毁旧交换链 - if (old_swapchain != VK_NULL_HANDLE) { - vkDestroySwapchainKHR(device_->get_device(), old_swapchain, nullptr); + if (old_swapchain) { + device_->get_device().destroySwapchainKHR(old_swapchain); } return result; diff --git a/src/render/swapchain.hpp b/src/render/swapchain.hpp index d4e5b6b..e993bc9 100644 --- a/src/render/swapchain.hpp +++ b/src/render/swapchain.hpp @@ -17,9 +17,12 @@ #include "vulkan_device.hpp" #include "object.hpp" +#define VULKAN_HPP_NO_EXCEPTIONS +#include #include #include #include +#include namespace milai { @@ -38,13 +41,13 @@ class swapchain; */ struct swapchain_config { /// 首选格式 - VkFormat preferred_format = VK_FORMAT_B8G8R8A8_SRGB; + vk::Format preferred_format = vk::Format::eB8G8R8A8Srgb; /// 首选颜色空间 - VkColorSpaceKHR preferred_color_space = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR; + vk::ColorSpaceKHR preferred_color_space = vk::ColorSpaceKHR::eSrgbNonlinear; /// 首选呈现模式(Mailbox 为三重缓冲,FIFO 为垂直同步) - VkPresentModeKHR preferred_present_mode = VK_PRESENT_MODE_MAILBOX_KHR; + vk::PresentModeKHR preferred_present_mode = vk::PresentModeKHR::eMailbox; /// 首选图像数量(0 表示自动选择) u32 preferred_image_count = 0; @@ -53,7 +56,7 @@ struct swapchain_config { bool enable_hdr = false; /// 旧交换链(用于重建时保持资源) - VkSwapchainKHR old_swapchain = VK_NULL_HANDLE; + vk::SwapchainKHR old_swapchain; }; // ================================================================================================ @@ -139,7 +142,7 @@ public: * @param config 交换链配置 */ swapchain(std::shared_ptr device, - VkSurfaceKHR surface, + vk::SurfaceKHR surface, u32 width, u32 height, const swapchain_config& config = {}); @@ -168,8 +171,8 @@ public: * @return 获取结果和图像索引 */ [[nodiscard]] std::pair acquire_next_image( - VkSemaphore semaphore, - VkFence fence = VK_NULL_HANDLE, + vk::Semaphore semaphore, + vk::Fence fence = {}, u64 timeout = UINT64_MAX); /** @@ -180,7 +183,7 @@ public: */ [[nodiscard]] present_result present( u32 image_index, - std::span wait_semaphores); + std::span wait_semaphores); /** * @brief 呈现图像(单个信号量版本) @@ -188,7 +191,7 @@ public: * @param wait_semaphore 呈现前等待的信号量 * @return 呈现结果 */ - [[nodiscard]] present_result present(u32 image_index, VkSemaphore wait_semaphore); + [[nodiscard]] present_result present(u32 image_index, vk::Semaphore wait_semaphore); // ============================================================================================ // 重建 @@ -216,9 +219,9 @@ public: /** * @brief 获取交换链句柄 - * @return VkSwapchainKHR 句柄 + * @return vk::SwapchainKHR 句柄 */ - [[nodiscard]] VkSwapchainKHR get_swapchain() const noexcept { + [[nodiscard]] vk::SwapchainKHR get_swapchain() const noexcept { return swapchain_; } @@ -227,13 +230,13 @@ public: * @return 如果有效返回 true */ [[nodiscard]] bool is_valid() const noexcept { - return swapchain_ != VK_NULL_HANDLE; + return !!swapchain_; } /** - * @brief 隐式转换为 VkSwapchainKHR + * @brief 隐式转换为 vk::SwapchainKHR */ - operator VkSwapchainKHR() const noexcept { + operator vk::SwapchainKHR() const noexcept { return swapchain_; } @@ -249,7 +252,7 @@ public: * @brief 获取所有图像 * @return 图像列表 */ - [[nodiscard]] const std::vector& get_images() const noexcept { + [[nodiscard]] const std::vector& get_images() const noexcept { return images_; } @@ -258,7 +261,7 @@ public: * @param index 图像索引 * @return 图像句柄 */ - [[nodiscard]] VkImage get_image(u32 index) const { + [[nodiscard]] vk::Image get_image(u32 index) const { return images_.at(index); } @@ -266,7 +269,7 @@ public: * @brief 获取所有图像视图 * @return 图像视图列表 */ - [[nodiscard]] const std::vector& get_image_views() const noexcept { + [[nodiscard]] const std::vector& get_image_views() const noexcept { return image_views_; } @@ -275,7 +278,7 @@ public: * @param index 图像索引 * @return 图像视图句柄 */ - [[nodiscard]] VkImageView get_image_view(u32 index) const { + [[nodiscard]] vk::ImageView get_image_view(u32 index) const { return image_views_.at(index); } @@ -283,7 +286,7 @@ public: * @brief 获取交换链格式 * @return 表面格式 */ - [[nodiscard]] VkFormat get_format() const noexcept { + [[nodiscard]] vk::Format get_format() const noexcept { return format_.format; } @@ -291,7 +294,7 @@ public: * @brief 获取表面格式(包含颜色空间) * @return 表面格式 */ - [[nodiscard]] VkSurfaceFormatKHR get_surface_format() const noexcept { + [[nodiscard]] vk::SurfaceFormatKHR get_surface_format() const noexcept { return format_; } @@ -299,7 +302,7 @@ public: * @brief 获取交换链范围 * @return 范围 */ - [[nodiscard]] VkExtent2D get_extent() const noexcept { + [[nodiscard]] vk::Extent2D get_extent() const noexcept { return extent_; } @@ -323,7 +326,7 @@ public: * @brief 获取呈现模式 * @return 呈现模式 */ - [[nodiscard]] VkPresentModeKHR get_present_mode() const noexcept { + [[nodiscard]] vk::PresentModeKHR get_present_mode() const noexcept { return present_mode_; } @@ -339,7 +342,7 @@ public: * @brief 获取表面 * @return 表面句柄 */ - [[nodiscard]] VkSurfaceKHR get_surface() const noexcept { + [[nodiscard]] vk::SurfaceKHR get_surface() const noexcept { return surface_; } @@ -385,25 +388,25 @@ private: std::shared_ptr device_; /// 表面句柄 - VkSurfaceKHR surface_ = VK_NULL_HANDLE; + vk::SurfaceKHR surface_; /// 交换链句柄 - VkSwapchainKHR swapchain_ = VK_NULL_HANDLE; + vk::SwapchainKHR swapchain_; /// 交换链图像 - std::vector images_; + std::vector images_; /// 图像视图 - std::vector image_views_; + std::vector image_views_; /// 表面格式 - VkSurfaceFormatKHR format_{}; + vk::SurfaceFormatKHR format_{}; /// 交换链范围 - VkExtent2D extent_{}; + vk::Extent2D extent_{}; /// 呈现模式 - VkPresentModeKHR present_mode_ = VK_PRESENT_MODE_FIFO_KHR; + vk::PresentModeKHR present_mode_ = vk::PresentModeKHR::eFifo; /// 配置 swapchain_config config_; diff --git a/src/render/vulkan_device.cpp b/src/render/vulkan_device.cpp index 7bf9c35..f3b70d5 100644 --- a/src/render/vulkan_device.cpp +++ b/src/render/vulkan_device.cpp @@ -19,40 +19,40 @@ namespace milai { // ================================================================================================ vulkan_device::vulkan_device(std::shared_ptr instance, - VkSurfaceKHR surface, + vk::SurfaceKHR surface, const vulkan_device_config& config) : instance_(std::move(instance)) { // 选择最佳物理设备 auto best_device = instance_->select_best_physical_device(surface); if (!best_device.has_value()) { - LOG_ERROR("No suitable GPU found"); + MILAI_LOG_ERROR("No suitable GPU found"); return; } auto result = create_logical_device(best_device.value(), surface, config); if (!result.has_value()) { - LOG_ERROR("Failed to create logical device: {}", result.error().message); + MILAI_LOG_ERROR("Failed to create logical device: {}", result.error().message); } } vulkan_device::vulkan_device(std::shared_ptr instance, const physical_device_info& physical_device, - VkSurfaceKHR surface, + vk::SurfaceKHR surface, const vulkan_device_config& config) : instance_(std::move(instance)) { auto result = create_logical_device(physical_device, surface, config); if (!result.has_value()) { - LOG_ERROR("Failed to create logical device: {}", result.error().message); + MILAI_LOG_ERROR("Failed to create logical device: {}", result.error().message); } } vulkan_device::~vulkan_device() { - if (device_ != VK_NULL_HANDLE) { + if (device_) { wait_idle(); - vkDestroyDevice(device_, nullptr); - device_ = VK_NULL_HANDLE; + device_.destroy(); + device_ = nullptr; } } @@ -61,11 +61,11 @@ vulkan_device::~vulkan_device() { // ================================================================================================ void vulkan_device::on_created() { - LOG_INFO("Vulkan device created: {}", get_device_name()); + MILAI_LOG_INFO("Vulkan device created: {}", get_device_name()); } void vulkan_device::on_destroying() { - LOG_INFO("Vulkan device destroying"); + MILAI_LOG_INFO("Vulkan device destroying"); } // ================================================================================================ @@ -74,7 +74,7 @@ void vulkan_device::on_destroying() { void_result vulkan_device::create_logical_device( const physical_device_info& device_info, - VkSurfaceKHR surface, + vk::SurfaceKHR surface, const vulkan_device_config& config) { physical_device_ = device_info.device; @@ -114,49 +114,45 @@ void_result vulkan_device::create_logical_device( } // 创建队列创建信息 - std::vector queue_create_infos; + std::vector queue_create_infos; auto unique_families = queue_families_.get_unique_families(); f32 queue_priority = 1.0f; for (u32 family : unique_families) { - VkDeviceQueueCreateInfo queue_info{}; - queue_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; - queue_info.queueFamilyIndex = family; - queue_info.queueCount = 1; - queue_info.pQueuePriorities = &queue_priority; + vk::DeviceQueueCreateInfo queue_info{}; + queue_info.setQueueFamilyIndex(family) + .setQueueCount(1) + .setPQueuePriorities(&queue_priority); queue_create_infos.push_back(queue_info); } // 设置要启用的特性 - VkPhysicalDeviceFeatures2 features2{}; - features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2; - features2.features = features_; + vk::PhysicalDeviceFeatures2 features2{}; + features2.setFeatures(features_); // 启用 Vulkan 1.2 特性 - VkPhysicalDeviceVulkan12Features enabled_features_12{}; - enabled_features_12.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES; - enabled_features_12.descriptorIndexing = features_12_.descriptorIndexing; - enabled_features_12.timelineSemaphore = features_12_.timelineSemaphore; - enabled_features_12.bufferDeviceAddress = features_12_.bufferDeviceAddress; - enabled_features_12.shaderSampledImageArrayNonUniformIndexing = - features_12_.shaderSampledImageArrayNonUniformIndexing; - enabled_features_12.runtimeDescriptorArray = features_12_.runtimeDescriptorArray; - enabled_features_12.descriptorBindingPartiallyBound = - features_12_.descriptorBindingPartiallyBound; - enabled_features_12.descriptorBindingVariableDescriptorCount = - features_12_.descriptorBindingVariableDescriptorCount; - enabled_features_12.hostQueryReset = features_12_.hostQueryReset; + vk::PhysicalDeviceVulkan12Features enabled_features_12{}; + enabled_features_12.setDescriptorIndexing(features_12_.descriptorIndexing) + .setTimelineSemaphore(features_12_.timelineSemaphore) + .setBufferDeviceAddress(features_12_.bufferDeviceAddress) + .setShaderSampledImageArrayNonUniformIndexing( + features_12_.shaderSampledImageArrayNonUniformIndexing) + .setRuntimeDescriptorArray(features_12_.runtimeDescriptorArray) + .setDescriptorBindingPartiallyBound( + features_12_.descriptorBindingPartiallyBound) + .setDescriptorBindingVariableDescriptorCount( + features_12_.descriptorBindingVariableDescriptorCount) + .setHostQueryReset(features_12_.hostQueryReset); // 启用 Vulkan 1.3 特性 - VkPhysicalDeviceVulkan13Features enabled_features_13{}; - enabled_features_13.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES; - enabled_features_13.dynamicRendering = features_13_.dynamicRendering; - enabled_features_13.synchronization2 = features_13_.synchronization2; - enabled_features_13.maintenance4 = features_13_.maintenance4; + vk::PhysicalDeviceVulkan13Features enabled_features_13{}; + enabled_features_13.setDynamicRendering(features_13_.dynamicRendering) + .setSynchronization2(features_13_.synchronization2) + .setMaintenance4(features_13_.maintenance4); // 链接特性结构 - features2.pNext = &enabled_features_12; - enabled_features_12.pNext = &enabled_features_13; + features2.setPNext(&enabled_features_12); + enabled_features_12.setPNext(&enabled_features_13); // 获取必需的扩展 enabled_extensions_ = get_required_extensions(config); @@ -178,51 +174,48 @@ void_result vulkan_device::create_logical_device( } // 设备创建信息 - VkDeviceCreateInfo create_info{}; - create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; - create_info.pNext = &features2; - create_info.queueCreateInfoCount = static_cast(queue_create_infos.size()); - create_info.pQueueCreateInfos = queue_create_infos.data(); - create_info.enabledExtensionCount = static_cast(enabled_extensions_.size()); - create_info.ppEnabledExtensionNames = enabled_extensions_.data(); - - // 为了兼容旧的实现,仍然设置 enabledLayerCount - // 但在现代 Vulkan 中,设备层已被弃用 - create_info.enabledLayerCount = 0; + vk::DeviceCreateInfo create_info{}; + create_info.setPNext(&features2) + .setQueueCreateInfoCount(static_cast(queue_create_infos.size())) + .setPQueueCreateInfos(queue_create_infos.data()) + .setEnabledExtensionCount(static_cast(enabled_extensions_.size())) + .setPpEnabledExtensionNames(enabled_extensions_.data()) + .setEnabledLayerCount(0); // 创建逻辑设备 - VkResult result = vkCreateDevice(physical_device_, &create_info, nullptr, &device_); - if (result != VK_SUCCESS) { + auto [result, device] = physical_device_.createDevice(create_info); + if (result != vk::Result::eSuccess) { return make_void_error(error_code::vulkan_init_failed, std::string("Failed to create logical device: ") + std::string(vk_result_to_string(result))); } + device_ = device; // 获取队列 if (queue_families_.graphics_family.has_value()) { - vkGetDeviceQueue(device_, queue_families_.graphics_family.value(), 0, &graphics_queue_); + graphics_queue_ = device_.getQueue(queue_families_.graphics_family.value(), 0); } if (queue_families_.present_family.has_value()) { - vkGetDeviceQueue(device_, queue_families_.present_family.value(), 0, &present_queue_); + present_queue_ = device_.getQueue(queue_families_.present_family.value(), 0); } if (queue_families_.compute_family.has_value()) { - vkGetDeviceQueue(device_, queue_families_.compute_family.value(), 0, &compute_queue_); + compute_queue_ = device_.getQueue(queue_families_.compute_family.value(), 0); } if (queue_families_.transfer_family.has_value()) { - vkGetDeviceQueue(device_, queue_families_.transfer_family.value(), 0, &transfer_queue_); + transfer_queue_ = device_.getQueue(queue_families_.transfer_family.value(), 0); } - LOG_INFO("Logical device created with {} queue(s)", unique_families.size()); - LOG_INFO(" Graphics queue family: {}", + MILAI_LOG_INFO("Logical device created with {} queue(s)", unique_families.size()); + MILAI_LOG_INFO(" Graphics queue family: {}", queue_families_.graphics_family.value_or(invalid_queue_family)); - LOG_INFO(" Present queue family: {}", + MILAI_LOG_INFO(" Present queue family: {}", queue_families_.present_family.value_or(invalid_queue_family)); - LOG_INFO(" Compute queue family: {}", + MILAI_LOG_INFO(" Compute queue family: {}", queue_families_.compute_family.value_or(invalid_queue_family)); - LOG_INFO(" Transfer queue family: {}", + MILAI_LOG_INFO(" Transfer queue family: {}", queue_families_.transfer_family.value_or(invalid_queue_family)); return make_success(); @@ -269,18 +262,15 @@ bool vulkan_device::is_extension_supported(const char* extension_name) const { return false; } -std::vector vulkan_device::get_available_extensions() const { - if (physical_device_ == VK_NULL_HANDLE) { +std::vector vulkan_device::get_available_extensions() const { + if (!physical_device_) { return {}; } - u32 extension_count = 0; - vkEnumerateDeviceExtensionProperties(physical_device_, nullptr, &extension_count, nullptr); - - std::vector extensions(extension_count); - vkEnumerateDeviceExtensionProperties(physical_device_, nullptr, &extension_count, - extensions.data()); - + auto [result, extensions] = physical_device_.enumerateDeviceExtensionProperties(); + if (result != vk::Result::eSuccess) { + return {}; + } return extensions; } @@ -289,19 +279,19 @@ std::vector vulkan_device::get_available_extensions() con // ================================================================================================ void vulkan_device::wait_idle() const { - if (device_ != VK_NULL_HANDLE) { - vkDeviceWaitIdle(device_); + if (device_) { + device_.waitIdle(); } } -void vulkan_device::wait_queue_idle(VkQueue queue) const { - if (queue != VK_NULL_HANDLE) { - vkQueueWaitIdle(queue); +void vulkan_device::wait_queue_idle(vk::Queue queue) const { + if (queue) { + queue.waitIdle(); } } std::optional vulkan_device::find_memory_type( - u32 type_filter, VkMemoryPropertyFlags properties) const + u32 type_filter, vk::MemoryPropertyFlags properties) const { for (u32 i = 0; i < memory_properties_.memoryTypeCount; ++i) { if ((type_filter & (1 << i)) && @@ -313,34 +303,33 @@ std::optional vulkan_device::find_memory_type( return std::nullopt; } -VkFormat vulkan_device::find_supported_format( - const std::vector& candidates, - VkImageTiling tiling, - VkFormatFeatureFlags features) const +vk::Format vulkan_device::find_supported_format( + const std::vector& candidates, + vk::ImageTiling tiling, + vk::FormatFeatureFlags features) const { - for (VkFormat format : candidates) { - VkFormatProperties props; - vkGetPhysicalDeviceFormatProperties(physical_device_, format, &props); + for (vk::Format format : candidates) { + vk::FormatProperties props = physical_device_.getFormatProperties(format); - if (tiling == VK_IMAGE_TILING_LINEAR && + if (tiling == vk::ImageTiling::eLinear && (props.linearTilingFeatures & features) == features) { return format; } - if (tiling == VK_IMAGE_TILING_OPTIMAL && + if (tiling == vk::ImageTiling::eOptimal && (props.optimalTilingFeatures & features) == features) { return format; } } - return VK_FORMAT_UNDEFINED; + return vk::Format::eUndefined; } -VkFormat vulkan_device::find_depth_format() const { +vk::Format vulkan_device::find_depth_format() const { return find_supported_format( - {VK_FORMAT_D32_SFLOAT, VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT}, - VK_IMAGE_TILING_OPTIMAL, - VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT + {vk::Format::eD32Sfloat, vk::Format::eD32SfloatS8Uint, vk::Format::eD24UnormS8Uint}, + vk::ImageTiling::eOptimal, + vk::FormatFeatureFlagBits::eDepthStencilAttachment ); } diff --git a/src/render/vulkan_device.hpp b/src/render/vulkan_device.hpp index 6ca5169..b7ac3ea 100644 --- a/src/render/vulkan_device.hpp +++ b/src/render/vulkan_device.hpp @@ -102,7 +102,7 @@ public: * @param config 设备配置 */ vulkan_device(std::shared_ptr instance, - VkSurfaceKHR surface, + vk::SurfaceKHR surface, const vulkan_device_config& config = {}); /** @@ -114,7 +114,7 @@ public: */ vulkan_device(std::shared_ptr instance, const physical_device_info& physical_device, - VkSurfaceKHR surface, + vk::SurfaceKHR surface, const vulkan_device_config& config = {}); /** @@ -134,17 +134,17 @@ public: /** * @brief 获取逻辑设备句柄 - * @return VkDevice 句柄 + * @return vk::Device 句柄 */ - [[nodiscard]] VkDevice get_device() const noexcept { + [[nodiscard]] vk::Device get_device() const noexcept { return device_; } /** * @brief 获取物理设备句柄 - * @return VkPhysicalDevice 句柄 + * @return vk::PhysicalDevice 句柄 */ - [[nodiscard]] VkPhysicalDevice get_physical_device() const noexcept { + [[nodiscard]] vk::PhysicalDevice get_physical_device() const noexcept { return physical_device_; } @@ -153,13 +153,13 @@ public: * @return 如果有效返回 true */ [[nodiscard]] bool is_valid() const noexcept { - return device_ != VK_NULL_HANDLE; + return !!device_; } /** - * @brief 隐式转换为 VkDevice + * @brief 隐式转换为 vk::Device */ - operator VkDevice() const noexcept { + operator vk::Device() const noexcept { return device_; } @@ -171,7 +171,7 @@ public: * @brief 获取图形队列 * @return 图形队列句柄 */ - [[nodiscard]] VkQueue get_graphics_queue() const noexcept { + [[nodiscard]] vk::Queue get_graphics_queue() const noexcept { return graphics_queue_; } @@ -179,7 +179,7 @@ public: * @brief 获取呈现队列 * @return 呈现队列句柄 */ - [[nodiscard]] VkQueue get_present_queue() const noexcept { + [[nodiscard]] vk::Queue get_present_queue() const noexcept { return present_queue_; } @@ -187,7 +187,7 @@ public: * @brief 获取计算队列 * @return 计算队列句柄 */ - [[nodiscard]] VkQueue get_compute_queue() const noexcept { + [[nodiscard]] vk::Queue get_compute_queue() const noexcept { return compute_queue_; } @@ -195,7 +195,7 @@ public: * @brief 获取传输队列 * @return 传输队列句柄 */ - [[nodiscard]] VkQueue get_transfer_queue() const noexcept { + [[nodiscard]] vk::Queue get_transfer_queue() const noexcept { return transfer_queue_; } @@ -247,7 +247,7 @@ public: * @brief 获取物理设备属性 * @return 物理设备属性 */ - [[nodiscard]] const VkPhysicalDeviceProperties& get_properties() const noexcept { + [[nodiscard]] const vk::PhysicalDeviceProperties& get_properties() const noexcept { return properties_; } @@ -255,7 +255,7 @@ public: * @brief 获取物理设备特性 * @return 物理设备特性 */ - [[nodiscard]] const VkPhysicalDeviceFeatures& get_features() const noexcept { + [[nodiscard]] const vk::PhysicalDeviceFeatures& get_features() const noexcept { return features_; } @@ -263,7 +263,7 @@ public: * @brief 获取物理设备内存属性 * @return 内存属性 */ - [[nodiscard]] const VkPhysicalDeviceMemoryProperties& get_memory_properties() const noexcept { + [[nodiscard]] const vk::PhysicalDeviceMemoryProperties& get_memory_properties() const noexcept { return memory_properties_; } @@ -272,7 +272,7 @@ public: * @return 设备名称 */ [[nodiscard]] std::string get_device_name() const { - return std::string(properties_.deviceName); + return std::string(properties_.deviceName.data()); } // ============================================================================================ @@ -342,7 +342,7 @@ public: * @brief 获取设备支持的所有扩展 * @return 扩展属性列表 */ - [[nodiscard]] std::vector get_available_extensions() const; + [[nodiscard]] std::vector get_available_extensions() const; // ============================================================================================ // 设备操作 @@ -357,7 +357,7 @@ public: * @brief 等待特定队列空闲 * @param queue 队列句柄 */ - void wait_queue_idle(VkQueue queue) const; + void wait_queue_idle(vk::Queue queue) const; /** * @brief 查找合适的内存类型 @@ -366,25 +366,25 @@ public: * @return 内存类型索引,如果找不到返回空 */ [[nodiscard]] std::optional find_memory_type( - u32 type_filter, VkMemoryPropertyFlags properties) const; + u32 type_filter, vk::MemoryPropertyFlags properties) const; /** * @brief 查找支持的格式 * @param candidates 候选格式列表 * @param tiling 平铺方式 * @param features 所需特性 - * @return 支持的格式,如果找不到返回 VK_FORMAT_UNDEFINED + * @return 支持的格式,如果找不到返回 vk::Format::eUndefined */ - [[nodiscard]] VkFormat find_supported_format( - const std::vector& candidates, - VkImageTiling tiling, - VkFormatFeatureFlags features) const; + [[nodiscard]] vk::Format find_supported_format( + const std::vector& candidates, + vk::ImageTiling tiling, + vk::FormatFeatureFlags features) const; /** * @brief 查找深度格式 * @return 支持的深度格式 */ - [[nodiscard]] VkFormat find_depth_format() const; + [[nodiscard]] vk::Format find_depth_format() const; /** * @brief 获取 Vulkan 实例 @@ -415,7 +415,7 @@ private: */ void_result create_logical_device( const physical_device_info& device_info, - VkSurfaceKHR surface, + vk::SurfaceKHR surface, const vulkan_device_config& config); /** @@ -430,44 +430,40 @@ private: std::shared_ptr instance_; /// 物理设备句柄 - VkPhysicalDevice physical_device_ = VK_NULL_HANDLE; + vk::PhysicalDevice physical_device_; /// 逻辑设备句柄 - VkDevice device_ = VK_NULL_HANDLE; + vk::Device device_; /// 队列族索引 queue_family_indices queue_families_; /// 图形队列 - VkQueue graphics_queue_ = VK_NULL_HANDLE; + vk::Queue graphics_queue_; /// 呈现队列 - VkQueue present_queue_ = VK_NULL_HANDLE; + vk::Queue present_queue_; /// 计算队列 - VkQueue compute_queue_ = VK_NULL_HANDLE; + vk::Queue compute_queue_; /// 传输队列 - VkQueue transfer_queue_ = VK_NULL_HANDLE; + vk::Queue transfer_queue_; /// 物理设备属性 - VkPhysicalDeviceProperties properties_{}; + vk::PhysicalDeviceProperties properties_{}; /// 物理设备特性 - VkPhysicalDeviceFeatures features_{}; + vk::PhysicalDeviceFeatures features_{}; /// Vulkan 1.2 特性 - VkPhysicalDeviceVulkan12Features features_12_{ - .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES - }; + vk::PhysicalDeviceVulkan12Features features_12_; /// Vulkan 1.3 特性 - VkPhysicalDeviceVulkan13Features features_13_{ - .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES - }; + vk::PhysicalDeviceVulkan13Features features_13_; /// 内存属性 - VkPhysicalDeviceMemoryProperties memory_properties_{}; + vk::PhysicalDeviceMemoryProperties memory_properties_{}; /// 已启用的扩展 std::vector enabled_extensions_; diff --git a/src/render/vulkan_instance.cpp b/src/render/vulkan_instance.cpp index c3ae18a..bb3fdbd 100644 --- a/src/render/vulkan_instance.cpp +++ b/src/render/vulkan_instance.cpp @@ -23,26 +23,26 @@ namespace milai { vulkan_instance::vulkan_instance(const vulkan_instance_config& config) { auto result = create_instance(config); if (!result.has_value()) { - LOG_ERROR("Failed to create Vulkan instance: {}", result.error().message); + MILAI_LOG_ERROR("Failed to create Vulkan instance: {}", result.error().message); return; } if (validation_enabled_) { result = setup_debug_messenger(); if (!result.has_value()) { - LOG_WARNING("Failed to setup debug messenger: {}", result.error().message); + MILAI_LOG_WARN("Failed to setup debug messenger: {}", result.error().message); } } } vulkan_instance::~vulkan_instance() { - if (debug_messenger_ != VK_NULL_HANDLE) { + if (debug_messenger_) { destroy_debug_messenger(); } - if (instance_ != VK_NULL_HANDLE) { - vkDestroyInstance(instance_, nullptr); - instance_ = VK_NULL_HANDLE; + if (instance_) { + instance_.destroy(); + instance_ = nullptr; } } @@ -51,11 +51,11 @@ vulkan_instance::~vulkan_instance() { // ================================================================================================ void vulkan_instance::on_created() { - LOG_INFO("Vulkan instance created"); + MILAI_LOG_INFO("Vulkan instance created"); } void vulkan_instance::on_destroying() { - LOG_INFO("Vulkan instance destroying"); + MILAI_LOG_INFO("Vulkan instance destroying"); } // ================================================================================================ @@ -66,7 +66,7 @@ void_result vulkan_instance::create_instance(const vulkan_instance_config& confi // 检查验证层支持 validation_enabled_ = config.enable_validation; if (validation_enabled_ && !is_layer_supported(validation_layer_name)) { - LOG_WARNING("Validation layer requested but not available, disabling"); + MILAI_LOG_WARN("Validation layer requested but not available, disabling"); validation_enabled_ = false; } @@ -79,13 +79,12 @@ void_result vulkan_instance::create_instance(const vulkan_instance_config& confi } // 应用信息 - VkApplicationInfo app_info{}; - app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; - app_info.pApplicationName = config.app_name.c_str(); - app_info.applicationVersion = config.app_version; - app_info.pEngineName = config.engine_name.c_str(); - app_info.engineVersion = config.engine_version; - app_info.apiVersion = api_version_; + vk::ApplicationInfo app_info{}; + app_info.setPApplicationName(config.app_name.c_str()) + .setApplicationVersion(config.app_version) + .setPEngineName(config.engine_name.c_str()) + .setEngineVersion(config.engine_version) + .setApiVersion(api_version_); // 获取必需的扩展 enabled_extensions_ = get_required_extensions(config); @@ -110,42 +109,40 @@ void_result vulkan_instance::create_instance(const vulkan_instance_config& confi } // 实例创建信息 - VkInstanceCreateInfo create_info{}; - create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; - create_info.pApplicationInfo = &app_info; - create_info.enabledExtensionCount = static_cast(enabled_extensions_.size()); - create_info.ppEnabledExtensionNames = enabled_extensions_.data(); - create_info.enabledLayerCount = static_cast(enabled_layers_.size()); - create_info.ppEnabledLayerNames = enabled_layers_.data(); + vk::InstanceCreateInfo create_info{}; + create_info.setPApplicationInfo(&app_info) + .setEnabledExtensionCount(static_cast(enabled_extensions_.size())) + .setPpEnabledExtensionNames(enabled_extensions_.data()) + .setEnabledLayerCount(static_cast(enabled_layers_.size())) + .setPpEnabledLayerNames(enabled_layers_.data()); // 调试信使创建信息(用于实例创建/销毁阶段的调试) VkDebugUtilsMessengerCreateInfoEXT debug_create_info{}; + debug_create_info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT; if (validation_enabled_) { - debug_create_info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT; - debug_create_info.messageSeverity = - VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT | - VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT | - VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT | - VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT; - debug_create_info.messageType = - VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | - VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | - VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT; + debug_create_info.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT | + VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT | + VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT | + VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT; + debug_create_info.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | + VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | + VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT; debug_create_info.pfnUserCallback = debug_callback; debug_create_info.pUserData = this; - create_info.pNext = &debug_create_info; + create_info.setPNext(&debug_create_info); } // 创建实例 - VkResult result = vkCreateInstance(&create_info, nullptr, &instance_); - if (result != VK_SUCCESS) { + auto [result, instance] = vk::createInstance(create_info); + if (result != vk::Result::eSuccess) { return make_void_error(error_code::vulkan_init_failed, - std::string("Failed to create Vulkan instance: ") + + std::string("Failed to create Vulkan instance: ") + std::string(vk_result_to_string(result))); } + instance_ = instance; - LOG_INFO("Vulkan instance created with API version {}.{}.{}", + MILAI_LOG_INFO("Vulkan instance created with API version {}.{}.{}", VK_VERSION_MAJOR(api_version_), VK_VERSION_MINOR(api_version_), VK_VERSION_PATCH(api_version_)); @@ -158,56 +155,56 @@ void_result vulkan_instance::create_instance(const vulkan_instance_config& confi // ================================================================================================ void_result vulkan_instance::setup_debug_messenger() { - if (!validation_enabled_ || instance_ == VK_NULL_HANDLE) { + if (!validation_enabled_ || !instance_) { return make_success(); } - // 获取函数指针 + // 使用 C API 创建调试信使 auto func = reinterpret_cast( - vkGetInstanceProcAddr(instance_, "vkCreateDebugUtilsMessengerEXT")); + vkGetInstanceProcAddr(static_cast(instance_), "vkCreateDebugUtilsMessengerEXT")); - if (func == nullptr) { + if (!func) { return make_void_error(error_code::vulkan_init_failed, - "Failed to get vkCreateDebugUtilsMessengerEXT function"); + "Could not load vkCreateDebugUtilsMessengerEXT"); } VkDebugUtilsMessengerCreateInfoEXT create_info{}; create_info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT; - create_info.messageSeverity = - VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT | - VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT | - VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT | - VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT; - create_info.messageType = - VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | - VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | - VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT; + create_info.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT | + VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT | + VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT | + VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT; + create_info.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | + VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | + VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT; create_info.pfnUserCallback = debug_callback; create_info.pUserData = this; - VkResult result = func(instance_, &create_info, nullptr, &debug_messenger_); + VkDebugUtilsMessengerEXT messenger = VK_NULL_HANDLE; + VkResult result = func(static_cast(instance_), &create_info, nullptr, &messenger); if (result != VK_SUCCESS) { return make_void_error(error_code::vulkan_init_failed, std::string("Failed to create debug messenger: ") + - std::string(vk_result_to_string(result))); + std::string(vk_result_to_string(static_cast(result)))); } + debug_messenger_ = messenger; - LOG_DEBUG("Vulkan debug messenger created"); + MILAI_LOG_DEBUG("Vulkan debug messenger created"); return make_success(); } void vulkan_instance::destroy_debug_messenger() { - if (debug_messenger_ == VK_NULL_HANDLE || instance_ == VK_NULL_HANDLE) { + if (!debug_messenger_ || !instance_) { return; } auto func = reinterpret_cast( - vkGetInstanceProcAddr(instance_, "vkDestroyDebugUtilsMessengerEXT")); + vkGetInstanceProcAddr(static_cast(instance_), "vkDestroyDebugUtilsMessengerEXT")); - if (func != nullptr) { - func(instance_, debug_messenger_, nullptr); - debug_messenger_ = VK_NULL_HANDLE; + if (func) { + func(static_cast(instance_), static_cast(debug_messenger_), nullptr); } + debug_messenger_ = nullptr; } void vulkan_instance::set_debug_callback(debug_callback_fn callback) { @@ -224,27 +221,21 @@ VKAPI_ATTR VkBool32 VKAPI_CALL vulkan_instance::debug_callback( // 转换严重级别 debug_severity severity; - switch (message_severity) { - case VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT: - severity = debug_severity::verbose; - break; - case VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT: - severity = debug_severity::info; - break; - case VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT: - severity = debug_severity::warning; - break; - case VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT: - default: - severity = debug_severity::error; - break; + if (message_severity & (VkDebugUtilsMessageSeverityFlagBitsEXT)vk::DebugUtilsMessageSeverityFlagBitsEXT::eVerbose) { + severity = debug_severity::verbose; + } else if (message_severity & (VkDebugUtilsMessageSeverityFlagBitsEXT)vk::DebugUtilsMessageSeverityFlagBitsEXT::eInfo) { + severity = debug_severity::info; + } else if (message_severity & (VkDebugUtilsMessageSeverityFlagBitsEXT)vk::DebugUtilsMessageSeverityFlagBitsEXT::eWarning) { + severity = debug_severity::warning; + } else { + severity = debug_severity::error; } // 转换消息类型 debug_type type; - if (message_type & VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT) { + if (message_type & (VkDebugUtilsMessageTypeFlagsEXT)vk::DebugUtilsMessageTypeFlagBitsEXT::eValidation) { type = debug_type::validation; - } else if (message_type & VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT) { + } else if (message_type & (VkDebugUtilsMessageTypeFlagsEXT)vk::DebugUtilsMessageTypeFlagBitsEXT::ePerformance) { type = debug_type::performance; } else { type = debug_type::general; @@ -258,16 +249,16 @@ VKAPI_ATTR VkBool32 VKAPI_CALL vulkan_instance::debug_callback( // 使用日志系统记录 switch (severity) { case debug_severity::verbose: - LOG_TRACE("[Vulkan] {}", callback_data->pMessage); + MILAI_LOG_TRACE("[Vulkan] {}", callback_data->pMessage); break; case debug_severity::info: - LOG_DEBUG("[Vulkan] {}", callback_data->pMessage); + MILAI_LOG_DEBUG("[Vulkan] {}", callback_data->pMessage); break; case debug_severity::warning: - LOG_WARNING("[Vulkan] {}", callback_data->pMessage); + MILAI_LOG_WARN("[Vulkan] {}", callback_data->pMessage); break; case debug_severity::error: - LOG_ERROR("[Vulkan] {}", callback_data->pMessage); + MILAI_LOG_ERROR("[Vulkan] {}", callback_data->pMessage); break; } @@ -278,32 +269,27 @@ VKAPI_ATTR VkBool32 VKAPI_CALL vulkan_instance::debug_callback( // 物理设备枚举 // ================================================================================================ -std::vector vulkan_instance::enumerate_physical_devices() const { - if (instance_ == VK_NULL_HANDLE) { +std::vector vulkan_instance::enumerate_physical_devices() const { + if (!instance_) { return {}; } - u32 device_count = 0; - vkEnumeratePhysicalDevices(instance_, &device_count, nullptr); - - if (device_count == 0) { + auto [result, devices] = instance_.enumeratePhysicalDevices(); + if (result != vk::Result::eSuccess) { return {}; } - std::vector devices(device_count); - vkEnumeratePhysicalDevices(instance_, &device_count, devices.data()); - return devices; } std::vector vulkan_instance::get_physical_devices_info( - VkSurfaceKHR surface) const + vk::SurfaceKHR surface) const { auto devices = enumerate_physical_devices(); std::vector infos; infos.reserve(devices.size()); - for (VkPhysicalDevice device : devices) { + for (const auto& device : devices) { auto info = populate_device_info(device, surface); info.score = info.calculate_score(); infos.push_back(std::move(info)); @@ -319,13 +305,13 @@ std::vector vulkan_instance::get_physical_devices_info( } std::optional vulkan_instance::select_best_physical_device( - VkSurfaceKHR surface) const + vk::SurfaceKHR surface) const { auto infos = get_physical_devices_info(surface); for (const auto& info : infos) { if (info.is_suitable()) { - LOG_INFO("Selected GPU: {} (score: {})", info.get_device_name(), info.score); + MILAI_LOG_INFO("Selected GPU: {} (score: {})", info.get_device_name(), info.score); return info; } } @@ -334,35 +320,30 @@ std::optional vulkan_instance::select_best_physical_device } physical_device_info vulkan_instance::populate_device_info( - VkPhysicalDevice device, VkSurfaceKHR surface) const + vk::PhysicalDevice device, vk::SurfaceKHR surface) const { physical_device_info info; info.device = device; // 获取基本属性和特性 - vkGetPhysicalDeviceProperties(device, &info.properties); - vkGetPhysicalDeviceFeatures(device, &info.features); - vkGetPhysicalDeviceMemoryProperties(device, &info.memory_properties); + info.properties = device.getProperties(); + info.features = device.getFeatures(); + info.memory_properties = device.getMemoryProperties(); // 获取 Vulkan 1.1/1.2/1.3 特性 - VkPhysicalDeviceFeatures2 features2{}; - features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2; + vk::PhysicalDeviceFeatures2 features2{}; - info.features_11.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES; - info.features_12.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES; - info.features_13.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES; + features2.setPNext(&info.features_11); + info.features_11.setPNext(&info.features_12); + info.features_12.setPNext(&info.features_13); - features2.pNext = &info.features_11; - info.features_11.pNext = &info.features_12; - info.features_12.pNext = &info.features_13; - - vkGetPhysicalDeviceFeatures2(device, &features2); + device.getFeatures2(&features2); // 获取队列族 info.queue_families = find_queue_families(device, surface); // 获取交换链支持 - if (surface != VK_NULL_HANDLE) { + if (surface) { info.swapchain_support = query_swapchain_support(device, surface); } @@ -370,49 +351,44 @@ physical_device_info vulkan_instance::populate_device_info( } queue_family_indices vulkan_instance::find_queue_families( - VkPhysicalDevice device, VkSurfaceKHR surface) const + vk::PhysicalDevice device, vk::SurfaceKHR surface) const { queue_family_indices indices; - u32 queue_family_count = 0; - vkGetPhysicalDeviceQueueFamilyProperties(device, &queue_family_count, nullptr); + std::vector queue_families = device.getQueueFamilyProperties(); - std::vector queue_families(queue_family_count); - vkGetPhysicalDeviceQueueFamilyProperties(device, &queue_family_count, queue_families.data()); - - for (u32 i = 0; i < queue_family_count; ++i) { + for (u32 i = 0; i < queue_families.size(); ++i) { const auto& queue_family = queue_families[i]; // 检查图形支持 - if (queue_family.queueFlags & VK_QUEUE_GRAPHICS_BIT) { + if (queue_family.queueFlags & vk::QueueFlagBits::eGraphics) { indices.graphics_family = i; } // 检查呈现支持 - if (surface != VK_NULL_HANDLE) { - VkBool32 present_support = VK_FALSE; - vkGetPhysicalDeviceSurfaceSupportKHR(device, i, surface, &present_support); - if (present_support) { + if (surface) { + auto [result, present_support] = device.getSurfaceSupportKHR(i, surface); + if (result == vk::Result::eSuccess && present_support) { indices.present_family = i; } } // 检查独立计算队列 - if ((queue_family.queueFlags & VK_QUEUE_COMPUTE_BIT) && - !(queue_family.queueFlags & VK_QUEUE_GRAPHICS_BIT)) { + if ((queue_family.queueFlags & vk::QueueFlagBits::eCompute) && + !(queue_family.queueFlags & vk::QueueFlagBits::eGraphics)) { indices.compute_family = i; - } else if (queue_family.queueFlags & VK_QUEUE_COMPUTE_BIT) { + } else if (queue_family.queueFlags & vk::QueueFlagBits::eCompute) { if (!indices.compute_family.has_value()) { indices.compute_family = i; } } // 检查独立传输队列 - if ((queue_family.queueFlags & VK_QUEUE_TRANSFER_BIT) && - !(queue_family.queueFlags & VK_QUEUE_GRAPHICS_BIT) && - !(queue_family.queueFlags & VK_QUEUE_COMPUTE_BIT)) { + if ((queue_family.queueFlags & vk::QueueFlagBits::eTransfer) && + !(queue_family.queueFlags & vk::QueueFlagBits::eGraphics) && + !(queue_family.queueFlags & vk::QueueFlagBits::eCompute)) { indices.transfer_family = i; - } else if (queue_family.queueFlags & VK_QUEUE_TRANSFER_BIT) { + } else if (queue_family.queueFlags & vk::QueueFlagBits::eTransfer) { if (!indices.transfer_family.has_value()) { indices.transfer_family = i; } @@ -423,32 +399,30 @@ queue_family_indices vulkan_instance::find_queue_families( } swapchain_support_details vulkan_instance::query_swapchain_support( - VkPhysicalDevice device, VkSurfaceKHR surface) const + vk::PhysicalDevice device, vk::SurfaceKHR surface) const { swapchain_support_details details; - if (surface == VK_NULL_HANDLE) { + if (!surface) { return details; } // 获取表面能力 - vkGetPhysicalDeviceSurfaceCapabilitiesKHR(device, surface, &details.capabilities); + auto [result_caps, capabilities] = device.getSurfaceCapabilitiesKHR(surface); + if (result_caps == vk::Result::eSuccess) { + details.capabilities = capabilities; + } // 获取表面格式 - u32 format_count = 0; - vkGetPhysicalDeviceSurfaceFormatsKHR(device, surface, &format_count, nullptr); - if (format_count > 0) { - details.formats.resize(format_count); - vkGetPhysicalDeviceSurfaceFormatsKHR(device, surface, &format_count, details.formats.data()); + auto [result_formats, formats] = device.getSurfaceFormatsKHR(surface); + if (result_formats == vk::Result::eSuccess) { + details.formats = formats; } // 获取呈现模式 - u32 present_mode_count = 0; - vkGetPhysicalDeviceSurfacePresentModesKHR(device, surface, &present_mode_count, nullptr); - if (present_mode_count > 0) { - details.present_modes.resize(present_mode_count); - vkGetPhysicalDeviceSurfacePresentModesKHR(device, surface, &present_mode_count, - details.present_modes.data()); + auto [result_modes, modes] = device.getSurfacePresentModesKHR(surface); + if (result_modes == vk::Result::eSuccess) { + details.present_modes = modes; } return details; @@ -515,38 +489,28 @@ bool vulkan_instance::is_layer_supported(const char* layer_name) { return false; } -std::vector vulkan_instance::get_available_extensions() { - u32 extension_count = 0; - vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, nullptr); - - std::vector extensions(extension_count); - vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, extensions.data()); - +std::vector vulkan_instance::get_available_extensions() { + auto [result, extensions] = vk::enumerateInstanceExtensionProperties(); + if (result != vk::Result::eSuccess) { + return {}; + } return extensions; } -std::vector vulkan_instance::get_available_layers() { - u32 layer_count = 0; - vkEnumerateInstanceLayerProperties(&layer_count, nullptr); - - std::vector layers(layer_count); - vkEnumerateInstanceLayerProperties(&layer_count, layers.data()); - +std::vector vulkan_instance::get_available_layers() { + auto [result, layers] = vk::enumerateInstanceLayerProperties(); + if (result != vk::Result::eSuccess) { + return {}; + } return layers; } u32 vulkan_instance::get_supported_api_version() { - u32 api_version = VK_API_VERSION_1_0; - - // vkEnumerateInstanceVersion 在 Vulkan 1.1+ 可用 - auto enumerate_version = reinterpret_cast( - vkGetInstanceProcAddr(nullptr, "vkEnumerateInstanceVersion")); - - if (enumerate_version != nullptr) { - enumerate_version(&api_version); + auto [result, version] = vk::enumerateInstanceVersion(); + if (result != vk::Result::eSuccess) { + return VK_API_VERSION_1_0; } - - return api_version; + return version; } } // namespace milai \ No newline at end of file diff --git a/src/render/vulkan_instance.hpp b/src/render/vulkan_instance.hpp index 7b40772..4484072 100644 --- a/src/render/vulkan_instance.hpp +++ b/src/render/vulkan_instance.hpp @@ -157,9 +157,9 @@ public: /** * @brief 获取 Vulkan 实例句柄 - * @return VkInstance 句柄 + * @return vk::Instance 句柄 */ - [[nodiscard]] VkInstance get_instance() const noexcept { + [[nodiscard]] vk::Instance get_instance() const noexcept { return instance_; } @@ -168,13 +168,13 @@ public: * @return 如果有效返回 true */ [[nodiscard]] bool is_valid() const noexcept { - return instance_ != VK_NULL_HANDLE; + return !!instance_; } /** - * @brief 隐式转换为 VkInstance + * @brief 隐式转换为 vk::Instance */ - operator VkInstance() const noexcept { + operator vk::Instance() const noexcept { return instance_; } @@ -204,7 +204,7 @@ public: * @brief 枚举所有物理设备 * @return 物理设备列表 */ - [[nodiscard]] std::vector enumerate_physical_devices() const; + [[nodiscard]] std::vector enumerate_physical_devices() const; /** * @brief 获取所有物理设备的详细信息 @@ -212,7 +212,7 @@ public: * @return 物理设备信息列表 */ [[nodiscard]] std::vector get_physical_devices_info( - VkSurfaceKHR surface = VK_NULL_HANDLE) const; + vk::SurfaceKHR surface = {}) const; /** * @brief 选择最佳物理设备 @@ -220,7 +220,7 @@ public: * @return 最佳物理设备信息,如果没有合适的设备返回空 */ [[nodiscard]] std::optional select_best_physical_device( - VkSurfaceKHR surface) const; + vk::SurfaceKHR surface) const; // ============================================================================================ // 扩展和层查询 @@ -260,13 +260,13 @@ public: * @brief 获取所有可用的实例扩展 * @return 扩展属性列表 */ - [[nodiscard]] static std::vector get_available_extensions(); + [[nodiscard]] static std::vector get_available_extensions(); /** * @brief 获取所有可用的验证层 * @return 层属性列表 */ - [[nodiscard]] static std::vector get_available_layers(); + [[nodiscard]] static std::vector get_available_layers(); // ============================================================================================ // API 版本 @@ -331,7 +331,7 @@ private: * @return 物理设备信息 */ [[nodiscard]] physical_device_info populate_device_info( - VkPhysicalDevice device, VkSurfaceKHR surface) const; + vk::PhysicalDevice device, vk::SurfaceKHR surface) const; /** * @brief 查找队列族 @@ -340,7 +340,7 @@ private: * @return 队列族索引 */ [[nodiscard]] queue_family_indices find_queue_families( - VkPhysicalDevice device, VkSurfaceKHR surface) const; + vk::PhysicalDevice device, vk::SurfaceKHR surface) const; /** * @brief 查询交换链支持 @@ -349,7 +349,7 @@ private: * @return 交换链支持详情 */ [[nodiscard]] swapchain_support_details query_swapchain_support( - VkPhysicalDevice device, VkSurfaceKHR surface) const; + vk::PhysicalDevice device, vk::SurfaceKHR surface) const; /** * @brief Vulkan 调试回调 @@ -361,10 +361,10 @@ private: void* user_data); /// Vulkan 实例句柄 - VkInstance instance_ = VK_NULL_HANDLE; + vk::Instance instance_; /// 调试信使句柄 - VkDebugUtilsMessengerEXT debug_messenger_ = VK_NULL_HANDLE; + vk::DebugUtilsMessengerEXT debug_messenger_; /// 是否启用验证层 bool validation_enabled_ = false; diff --git a/src/render/vulkan_types.hpp b/src/render/vulkan_types.hpp index 5328d3f..dfac82e 100644 --- a/src/render/vulkan_types.hpp +++ b/src/render/vulkan_types.hpp @@ -16,7 +16,9 @@ #include "types.hpp" -#include +#define VULKAN_HPP_NO_EXCEPTIONS +#define VULKAN_HPP_DISPATCH_LOADER_DYNAMIC 1 +#include #include #include @@ -157,13 +159,13 @@ struct queue_family_indices { */ struct swapchain_support_details { /// 表面能力 - VkSurfaceCapabilitiesKHR capabilities{}; + vk::SurfaceCapabilitiesKHR capabilities{}; /// 支持的表面格式列表 - std::vector formats; + std::vector formats; /// 支持的呈现模式列表 - std::vector present_modes; + std::vector present_modes; /** * @brief 检查交换链支持是否足够 @@ -179,21 +181,21 @@ struct swapchain_support_details { * @param preferred_color_space 首选颜色空间 * @return 选择的表面格式 */ - [[nodiscard]] VkSurfaceFormatKHR choose_surface_format( - VkFormat preferred_format = VK_FORMAT_B8G8R8A8_SRGB, - VkColorSpaceKHR preferred_color_space = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR + [[nodiscard]] vk::SurfaceFormatKHR choose_surface_format( + vk::Format preferred_format = vk::Format::eB8G8R8A8Srgb, + vk::ColorSpaceKHR preferred_color_space = vk::ColorSpaceKHR::eSrgbNonlinear ) const { // 首先尝试找到首选格式 for (const auto& format : formats) { - if (format.format == preferred_format && + if (format.format == preferred_format && format.colorSpace == preferred_color_space) { return format; } } // 如果找不到首选格式,返回第一个可用格式 - return formats.empty() ? VkSurfaceFormatKHR{VK_FORMAT_B8G8R8A8_UNORM, - VK_COLOR_SPACE_SRGB_NONLINEAR_KHR} + return formats.empty() ? vk::SurfaceFormatKHR{vk::Format::eB8G8R8A8Unorm, + vk::ColorSpaceKHR::eSrgbNonlinear} : formats[0]; } @@ -202,8 +204,8 @@ struct swapchain_support_details { * @param preferred_mode 首选模式 * @return 选择的呈现模式 */ - [[nodiscard]] VkPresentModeKHR choose_present_mode( - VkPresentModeKHR preferred_mode = VK_PRESENT_MODE_MAILBOX_KHR + [[nodiscard]] vk::PresentModeKHR choose_present_mode( + vk::PresentModeKHR preferred_mode = vk::PresentModeKHR::eMailbox ) const { // 首先尝试找到首选模式 for (const auto& mode : present_modes) { @@ -213,7 +215,7 @@ struct swapchain_support_details { } // 如果找不到首选模式,返回 FIFO(总是可用) - return VK_PRESENT_MODE_FIFO_KHR; + return vk::PresentModeKHR::eFifo; } /** @@ -222,12 +224,12 @@ struct swapchain_support_details { * @param window_height 窗口高度 * @return 选择的范围 */ - [[nodiscard]] VkExtent2D choose_extent(u32 window_width, u32 window_height) const { + [[nodiscard]] vk::Extent2D choose_extent(u32 window_width, u32 window_height) const { if (capabilities.currentExtent.width != std::numeric_limits::max()) { return capabilities.currentExtent; } - VkExtent2D actual_extent = {window_width, window_height}; + vk::Extent2D actual_extent = {window_width, window_height}; actual_extent.width = std::clamp(actual_extent.width, capabilities.minImageExtent.width, @@ -266,31 +268,25 @@ struct swapchain_support_details { */ struct physical_device_info { /// 物理设备句柄 - VkPhysicalDevice device = VK_NULL_HANDLE; + vk::PhysicalDevice device; /// 设备属性 - VkPhysicalDeviceProperties properties{}; + vk::PhysicalDeviceProperties properties{}; /// 设备特性 - VkPhysicalDeviceFeatures features{}; + vk::PhysicalDeviceFeatures features{}; /// Vulkan 1.1 特性 - VkPhysicalDeviceVulkan11Features features_11{ - .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES - }; + vk::PhysicalDeviceVulkan11Features features_11; /// Vulkan 1.2 特性 - VkPhysicalDeviceVulkan12Features features_12{ - .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES - }; + vk::PhysicalDeviceVulkan12Features features_12; /// Vulkan 1.3 特性 - VkPhysicalDeviceVulkan13Features features_13{ - .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES - }; + vk::PhysicalDeviceVulkan13Features features_13; /// 设备内存属性 - VkPhysicalDeviceMemoryProperties memory_properties{}; + vk::PhysicalDeviceMemoryProperties memory_properties{}; /// 队列族索引 queue_family_indices queue_families; @@ -306,7 +302,7 @@ struct physical_device_info { * @return 设备名称字符串 */ [[nodiscard]] std::string get_device_name() const { - return std::string(properties.deviceName); + return std::string(properties.deviceName.data()); } /** @@ -314,7 +310,7 @@ struct physical_device_info { * @return 如果是独立 GPU 返回 true */ [[nodiscard]] bool is_discrete_gpu() const noexcept { - return properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU; + return properties.deviceType == vk::PhysicalDeviceType::eDiscreteGpu; } /** @@ -322,7 +318,7 @@ struct physical_device_info { * @return 如果是集成 GPU 返回 true */ [[nodiscard]] bool is_integrated_gpu() const noexcept { - return properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU; + return properties.deviceType == vk::PhysicalDeviceType::eIntegratedGpu; } /** @@ -338,7 +334,7 @@ struct physical_device_info { * @return 如果支持 Dynamic Rendering 返回 true */ [[nodiscard]] bool supports_dynamic_rendering() const noexcept { - return features_13.dynamicRendering == VK_TRUE; + return features_13.dynamicRendering == vk::True; } /** @@ -346,7 +342,7 @@ struct physical_device_info { * @return 如果支持 Synchronization2 返回 true */ [[nodiscard]] bool supports_synchronization2() const noexcept { - return features_13.synchronization2 == VK_TRUE; + return features_13.synchronization2 == vk::True; } /** @@ -354,7 +350,7 @@ struct physical_device_info { * @return 如果支持描述符索引返回 true */ [[nodiscard]] bool supports_descriptor_indexing() const noexcept { - return features_12.descriptorIndexing == VK_TRUE; + return features_12.descriptorIndexing == vk::True; } /** @@ -362,7 +358,7 @@ struct physical_device_info { * @return 如果支持 Timeline Semaphores 返回 true */ [[nodiscard]] bool supports_timeline_semaphores() const noexcept { - return features_12.timelineSemaphore == VK_TRUE; + return features_12.timelineSemaphore == vk::True; } /** @@ -370,7 +366,7 @@ struct physical_device_info { * @return 如果支持 Buffer Device Address 返回 true */ [[nodiscard]] bool supports_buffer_device_address() const noexcept { - return features_12.bufferDeviceAddress == VK_TRUE; + return features_12.bufferDeviceAddress == vk::True; } /** @@ -378,7 +374,7 @@ struct physical_device_info { * @return 如果设备满足最低要求返回 true */ [[nodiscard]] bool is_suitable() const noexcept { - return device != VK_NULL_HANDLE && + return device && queue_families.is_complete() && swapchain_support.is_adequate() && supports_vulkan_1_3() && @@ -395,40 +391,40 @@ struct physical_device_info { return 0; } - i32 score = 0; + i32 device_score = 0; // 独立 GPU 加分 if (is_discrete_gpu()) { - score += 1000; + device_score += 1000; } else if (is_integrated_gpu()) { - score += 100; + device_score += 100; } // 最大纹理尺寸加分 - score += static_cast(properties.limits.maxImageDimension2D / 1000); + device_score += static_cast(properties.limits.maxImageDimension2D / 1000); // 支持可选特性加分 if (supports_descriptor_indexing()) { - score += 100; + device_score += 100; } if (supports_timeline_semaphores()) { - score += 50; + device_score += 50; } if (supports_buffer_device_address()) { - score += 50; + device_score += 50; } // 有独立计算队列加分 if (queue_families.has_dedicated_compute()) { - score += 50; + device_score += 50; } // 有独立传输队列加分 if (queue_families.has_dedicated_transfer()) { - score += 50; + device_score += 50; } - return score; + return device_score; } }; @@ -441,40 +437,8 @@ struct physical_device_info { * @param result Vulkan 结果码 * @return 结果描述字符串 */ -[[nodiscard]] constexpr std::string_view vk_result_to_string(VkResult result) noexcept { - switch (result) { - case VK_SUCCESS: return "VK_SUCCESS"; - case VK_NOT_READY: return "VK_NOT_READY"; - case VK_TIMEOUT: return "VK_TIMEOUT"; - case VK_EVENT_SET: return "VK_EVENT_SET"; - case VK_EVENT_RESET: return "VK_EVENT_RESET"; - case VK_INCOMPLETE: return "VK_INCOMPLETE"; - case VK_ERROR_OUT_OF_HOST_MEMORY: return "VK_ERROR_OUT_OF_HOST_MEMORY"; - case VK_ERROR_OUT_OF_DEVICE_MEMORY: return "VK_ERROR_OUT_OF_DEVICE_MEMORY"; - case VK_ERROR_INITIALIZATION_FAILED: return "VK_ERROR_INITIALIZATION_FAILED"; - case VK_ERROR_DEVICE_LOST: return "VK_ERROR_DEVICE_LOST"; - case VK_ERROR_MEMORY_MAP_FAILED: return "VK_ERROR_MEMORY_MAP_FAILED"; - case VK_ERROR_LAYER_NOT_PRESENT: return "VK_ERROR_LAYER_NOT_PRESENT"; - case VK_ERROR_EXTENSION_NOT_PRESENT: return "VK_ERROR_EXTENSION_NOT_PRESENT"; - case VK_ERROR_FEATURE_NOT_PRESENT: return "VK_ERROR_FEATURE_NOT_PRESENT"; - case VK_ERROR_INCOMPATIBLE_DRIVER: return "VK_ERROR_INCOMPATIBLE_DRIVER"; - case VK_ERROR_TOO_MANY_OBJECTS: return "VK_ERROR_TOO_MANY_OBJECTS"; - case VK_ERROR_FORMAT_NOT_SUPPORTED: return "VK_ERROR_FORMAT_NOT_SUPPORTED"; - case VK_ERROR_FRAGMENTED_POOL: return "VK_ERROR_FRAGMENTED_POOL"; - case VK_ERROR_UNKNOWN: return "VK_ERROR_UNKNOWN"; - case VK_ERROR_OUT_OF_POOL_MEMORY: return "VK_ERROR_OUT_OF_POOL_MEMORY"; - case VK_ERROR_INVALID_EXTERNAL_HANDLE: return "VK_ERROR_INVALID_EXTERNAL_HANDLE"; - case VK_ERROR_FRAGMENTATION: return "VK_ERROR_FRAGMENTATION"; - case VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS: return "VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS"; - case VK_ERROR_SURFACE_LOST_KHR: return "VK_ERROR_SURFACE_LOST_KHR"; - case VK_ERROR_NATIVE_WINDOW_IN_USE_KHR: return "VK_ERROR_NATIVE_WINDOW_IN_USE_KHR"; - case VK_SUBOPTIMAL_KHR: return "VK_SUBOPTIMAL_KHR"; - case VK_ERROR_OUT_OF_DATE_KHR: return "VK_ERROR_OUT_OF_DATE_KHR"; - case VK_ERROR_INCOMPATIBLE_DISPLAY_KHR: return "VK_ERROR_INCOMPATIBLE_DISPLAY_KHR"; - case VK_ERROR_VALIDATION_FAILED_EXT: return "VK_ERROR_VALIDATION_FAILED_EXT"; - case VK_ERROR_INVALID_SHADER_NV: return "VK_ERROR_INVALID_SHADER_NV"; - default: return "VK_UNKNOWN_ERROR"; - } +[[nodiscard]] inline std::string vk_result_to_string(vk::Result result) { + return vk::to_string(result); } /** @@ -482,8 +446,8 @@ struct physical_device_info { * @param result Vulkan 结果码 * @return 如果成功返回 true */ -[[nodiscard]] constexpr bool vk_succeeded(VkResult result) noexcept { - return result == VK_SUCCESS || result == VK_SUBOPTIMAL_KHR; +[[nodiscard]] constexpr bool vk_succeeded(vk::Result result) noexcept { + return result == vk::Result::eSuccess || result == vk::Result::eSuboptimalKHR; } /** @@ -491,8 +455,8 @@ struct physical_device_info { * @param result Vulkan 结果码 * @return 如果失败返回 true */ -[[nodiscard]] constexpr bool vk_failed(VkResult result) noexcept { - return result < 0; +[[nodiscard]] constexpr bool vk_failed(vk::Result result) noexcept { + return static_cast(result) < 0; } // ================================================================================================ @@ -505,7 +469,7 @@ struct physical_device_info { */ #define VK_CHECK(expr) \ do { \ - VkResult _result = (expr); \ + vk::Result _result = (expr); \ if (::milai::vk_failed(_result)) { \ return ::milai::make_error().dummy_result_type())>( \ ::milai::error_code::vulkan_init_failed, \ @@ -519,7 +483,7 @@ struct physical_device_info { */ #define VK_CHECK_VOID(expr) \ do { \ - VkResult _result = (expr); \ + vk::Result _result = (expr); \ if (::milai::vk_failed(_result)) { \ return ::milai::make_void_error( \ ::milai::error_code::vulkan_init_failed, \ @@ -536,16 +500,16 @@ struct physical_device_info { */ struct memory_barrier_config { /// 源阶段掩码 - VkPipelineStageFlags2 src_stage_mask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT; + vk::PipelineStageFlags2 src_stage_mask = vk::PipelineStageFlagBits2::eAllCommands; /// 源访问掩码 - VkAccessFlags2 src_access_mask = VK_ACCESS_2_MEMORY_WRITE_BIT; + vk::AccessFlags2 src_access_mask = vk::AccessFlagBits2::eMemoryWrite; /// 目标阶段掩码 - VkPipelineStageFlags2 dst_stage_mask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT; + vk::PipelineStageFlags2 dst_stage_mask = vk::PipelineStageFlagBits2::eAllCommands; /// 目标访问掩码 - VkAccessFlags2 dst_access_mask = VK_ACCESS_2_MEMORY_READ_BIT | VK_ACCESS_2_MEMORY_WRITE_BIT; + vk::AccessFlags2 dst_access_mask = vk::AccessFlagBits2::eMemoryRead | vk::AccessFlagBits2::eMemoryWrite; }; /** @@ -553,22 +517,22 @@ struct memory_barrier_config { */ struct image_memory_barrier_config { /// 源阶段掩码 - VkPipelineStageFlags2 src_stage_mask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT; + vk::PipelineStageFlags2 src_stage_mask = vk::PipelineStageFlagBits2::eAllCommands; /// 源访问掩码 - VkAccessFlags2 src_access_mask = VK_ACCESS_2_MEMORY_WRITE_BIT; + vk::AccessFlags2 src_access_mask = vk::AccessFlagBits2::eMemoryWrite; /// 目标阶段掩码 - VkPipelineStageFlags2 dst_stage_mask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT; + vk::PipelineStageFlags2 dst_stage_mask = vk::PipelineStageFlagBits2::eAllCommands; /// 目标访问掩码 - VkAccessFlags2 dst_access_mask = VK_ACCESS_2_MEMORY_READ_BIT | VK_ACCESS_2_MEMORY_WRITE_BIT; + vk::AccessFlags2 dst_access_mask = vk::AccessFlagBits2::eMemoryRead | vk::AccessFlagBits2::eMemoryWrite; /// 旧布局 - VkImageLayout old_layout = VK_IMAGE_LAYOUT_UNDEFINED; + vk::ImageLayout old_layout = vk::ImageLayout::eUndefined; /// 新布局 - VkImageLayout new_layout = VK_IMAGE_LAYOUT_UNDEFINED; + vk::ImageLayout new_layout = vk::ImageLayout::eUndefined; /// 源队列族索引 u32 src_queue_family_index = VK_QUEUE_FAMILY_IGNORED; @@ -577,15 +541,15 @@ struct image_memory_barrier_config { u32 dst_queue_family_index = VK_QUEUE_FAMILY_IGNORED; /// 图像句柄 - VkImage image = VK_NULL_HANDLE; + vk::Image image; /// 子资源范围 - VkImageSubresourceRange subresource_range = { - .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, - .baseMipLevel = 0, - .levelCount = 1, - .baseArrayLayer = 0, - .layerCount = 1 + vk::ImageSubresourceRange subresource_range = { + vk::ImageAspectFlagBits::eColor, + 0, + 1, + 0, + 1 }; }; @@ -594,16 +558,16 @@ struct image_memory_barrier_config { */ struct buffer_memory_barrier_config { /// 源阶段掩码 - VkPipelineStageFlags2 src_stage_mask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT; + vk::PipelineStageFlags2 src_stage_mask = vk::PipelineStageFlagBits2::eAllCommands; /// 源访问掩码 - VkAccessFlags2 src_access_mask = VK_ACCESS_2_MEMORY_WRITE_BIT; + vk::AccessFlags2 src_access_mask = vk::AccessFlagBits2::eMemoryWrite; /// 目标阶段掩码 - VkPipelineStageFlags2 dst_stage_mask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT; + vk::PipelineStageFlags2 dst_stage_mask = vk::PipelineStageFlagBits2::eAllCommands; /// 目标访问掩码 - VkAccessFlags2 dst_access_mask = VK_ACCESS_2_MEMORY_READ_BIT | VK_ACCESS_2_MEMORY_WRITE_BIT; + vk::AccessFlags2 dst_access_mask = vk::AccessFlagBits2::eMemoryRead | vk::AccessFlagBits2::eMemoryWrite; /// 源队列族索引 u32 src_queue_family_index = VK_QUEUE_FAMILY_IGNORED; @@ -612,13 +576,13 @@ struct buffer_memory_barrier_config { u32 dst_queue_family_index = VK_QUEUE_FAMILY_IGNORED; /// Buffer 句柄 - VkBuffer buffer = VK_NULL_HANDLE; + vk::Buffer buffer; /// 偏移量 - VkDeviceSize offset = 0; + vk::DeviceSize offset = 0; /// 大小 - VkDeviceSize size = VK_WHOLE_SIZE; + vk::DeviceSize size = VK_WHOLE_SIZE; }; // ================================================================================================ @@ -630,46 +594,44 @@ struct buffer_memory_barrier_config { */ struct color_attachment_info { /// 图像视图 - VkImageView image_view = VK_NULL_HANDLE; + vk::ImageView image_view; /// 图像布局 - VkImageLayout image_layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + vk::ImageLayout image_layout = vk::ImageLayout::eColorAttachmentOptimal; /// 解析模式(用于 MSAA) - VkResolveModeFlagBits resolve_mode = VK_RESOLVE_MODE_NONE; + vk::ResolveModeFlagBits resolve_mode = vk::ResolveModeFlagBits::eNone; /// 解析图像视图 - VkImageView resolve_image_view = VK_NULL_HANDLE; + vk::ImageView resolve_image_view; /// 解析图像布局 - VkImageLayout resolve_image_layout = VK_IMAGE_LAYOUT_UNDEFINED; + vk::ImageLayout resolve_image_layout = vk::ImageLayout::eUndefined; /// 加载操作 - VkAttachmentLoadOp load_op = VK_ATTACHMENT_LOAD_OP_CLEAR; + vk::AttachmentLoadOp load_op = vk::AttachmentLoadOp::eClear; /// 存储操作 - VkAttachmentStoreOp store_op = VK_ATTACHMENT_STORE_OP_STORE; + vk::AttachmentStoreOp store_op = vk::AttachmentStoreOp::eStore; /// 清除值 - VkClearColorValue clear_value = {{0.0f, 0.0f, 0.0f, 1.0f}}; + vk::ClearColorValue clear_value = std::array{0.0f, 0.0f, 0.0f, 1.0f}; /** - * @brief 转换为 VkRenderingAttachmentInfo + * @brief 转换为 vk::RenderingAttachmentInfo * @return Vulkan 渲染附件信息 */ - [[nodiscard]] VkRenderingAttachmentInfo to_vulkan() const { - return VkRenderingAttachmentInfo{ - .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, - .pNext = nullptr, - .imageView = image_view, - .imageLayout = image_layout, - .resolveMode = resolve_mode, - .resolveImageView = resolve_image_view, - .resolveImageLayout = resolve_image_layout, - .loadOp = load_op, - .storeOp = store_op, - .clearValue = {.color = clear_value} - }; + [[nodiscard]] vk::RenderingAttachmentInfo to_vulkan() const { + vk::RenderingAttachmentInfo info{}; + info.imageView = image_view; + info.imageLayout = image_layout; + info.resolveMode = resolve_mode; + info.resolveImageView = resolve_image_view; + info.resolveImageLayout = resolve_image_layout; + info.loadOp = load_op; + info.storeOp = store_op; + info.clearValue.color = clear_value; + return info; } }; @@ -678,25 +640,25 @@ struct color_attachment_info { */ struct depth_attachment_info { /// 图像视图 - VkImageView image_view = VK_NULL_HANDLE; + vk::ImageView image_view; /// 图像布局 - VkImageLayout image_layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + vk::ImageLayout image_layout = vk::ImageLayout::eDepthStencilAttachmentOptimal; /// 解析模式(用于 MSAA) - VkResolveModeFlagBits resolve_mode = VK_RESOLVE_MODE_NONE; + vk::ResolveModeFlagBits resolve_mode = vk::ResolveModeFlagBits::eNone; /// 解析图像视图 - VkImageView resolve_image_view = VK_NULL_HANDLE; + vk::ImageView resolve_image_view; /// 解析图像布局 - VkImageLayout resolve_image_layout = VK_IMAGE_LAYOUT_UNDEFINED; + vk::ImageLayout resolve_image_layout = vk::ImageLayout::eUndefined; /// 加载操作 - VkAttachmentLoadOp load_op = VK_ATTACHMENT_LOAD_OP_CLEAR; + vk::AttachmentLoadOp load_op = vk::AttachmentLoadOp::eClear; /// 存储操作 - VkAttachmentStoreOp store_op = VK_ATTACHMENT_STORE_OP_DONT_CARE; + vk::AttachmentStoreOp store_op = vk::AttachmentStoreOp::eDontCare; /// 深度清除值 f32 clear_depth = 1.0f; @@ -705,22 +667,20 @@ struct depth_attachment_info { u32 clear_stencil = 0; /** - * @brief 转换为 VkRenderingAttachmentInfo + * @brief 转换为 vk::RenderingAttachmentInfo * @return Vulkan 渲染附件信息 */ - [[nodiscard]] VkRenderingAttachmentInfo to_vulkan() const { - return VkRenderingAttachmentInfo{ - .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, - .pNext = nullptr, - .imageView = image_view, - .imageLayout = image_layout, - .resolveMode = resolve_mode, - .resolveImageView = resolve_image_view, - .resolveImageLayout = resolve_image_layout, - .loadOp = load_op, - .storeOp = store_op, - .clearValue = {.depthStencil = {clear_depth, clear_stencil}} - }; + [[nodiscard]] vk::RenderingAttachmentInfo to_vulkan() const { + vk::RenderingAttachmentInfo info{}; + info.imageView = image_view; + info.imageLayout = image_layout; + info.resolveMode = resolve_mode; + info.resolveImageView = resolve_image_view; + info.resolveImageLayout = resolve_image_layout; + info.loadOp = load_op; + info.storeOp = store_op; + info.clearValue.depthStencil = vk::ClearDepthStencilValue{clear_depth, clear_stencil}; + return info; } }; diff --git a/src/resource/CMakeLists.txt b/src/resource/CMakeLists.txt index 1c2a009..9c20e8b 100644 --- a/src/resource/CMakeLists.txt +++ b/src/resource/CMakeLists.txt @@ -5,7 +5,7 @@ project(milai_resource) simple_library(STATIC) -target_link_libraries(${PROJECT_NAME} PUBLIC milai_core milai_threading Vulkan::Vulkan) +target_link_libraries(${PROJECT_NAME} PUBLIC milai_core milai_render milai_threading Vulkan::Vulkan) target_link_directories(${PROJECT_NAME} PRIVATE ${Stb_INCLUDE_DIR}) set_target_properties(${PROJECT_NAME} PROPERTIES VERSION ${PROJECT_VERSION} diff --git a/src/resource/allocator.cpp b/src/resource/allocator.cpp index f085731..ce39182 100644 --- a/src/resource/allocator.cpp +++ b/src/resource/allocator.cpp @@ -22,7 +22,7 @@ gpu_allocator::gpu_allocator(const allocator_config& config) , enable_buffer_device_address_(config.enable_buffer_device_address) { auto result = initialize_vma(config); if (!result.has_value()) { - log_error("Failed to initialize VMA allocator: {}", result.error().message); + MILAI_LOG_ERROR("Failed to initialize VMA allocator: {}", result.error().message); } } @@ -56,9 +56,9 @@ void_result gpu_allocator::initialize_vma(const allocator_config& config) { VmaAllocatorCreateInfo allocator_info{}; allocator_info.vulkanApiVersion = config.vulkan_api_version; - allocator_info.physicalDevice = config.physical_device; - allocator_info.device = config.device; - allocator_info.instance = config.instance; + allocator_info.physicalDevice = static_cast(config.physical_device); + allocator_info.device = static_cast(config.device); + allocator_info.instance = static_cast(config.instance); allocator_info.pVulkanFunctions = &vulkan_functions; allocator_info.preferredLargeHeapBlockSize = config.preferred_large_heap_block_size; @@ -81,7 +81,7 @@ void_result gpu_allocator::initialize_vma(const allocator_config& config) { "Failed to create VMA allocator: " + std::to_string(result)); } - log_info("VMA allocator initialized successfully"); + MILAI_LOG_INFO("VMA allocator initialized successfully"); return make_success(); } @@ -94,9 +94,9 @@ result gpu_allocator::allocate_buffer(const buffer_allocation // 创建 Buffer 信息 VkBufferCreateInfo buffer_info{}; - buffer_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; - buffer_info.size = info.size; - buffer_info.usage = to_vulkan_buffer_usage(info.usage); + buffer_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; + buffer_info.size = info.size; + buffer_info.usage = to_vulkan_buffer_usage(info.usage); buffer_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; // 如果启用了 Buffer Device Address 并且用途包含此标志 @@ -111,23 +111,26 @@ result gpu_allocator::allocate_buffer(const buffer_allocation // 执行分配 VmaAllocationInfo vma_alloc_info{}; - VkResult result; + VkResult vk_result; + VkBuffer vk_buffer = VK_NULL_HANDLE; { std::lock_guard lock(mutex_); - result = vmaCreateBuffer(allocator_, &buffer_info, &alloc_info, - &alloc.buffer, &alloc.allocation, &vma_alloc_info); + vk_result = vmaCreateBuffer(allocator_, &buffer_info, &alloc_info, + &vk_buffer, &alloc.allocation, &vma_alloc_info); } - if (result != VK_SUCCESS) { + if (vk_result != VK_SUCCESS) { return make_error(error_code::out_of_memory, - "Failed to allocate buffer: " + std::to_string(result)); + "Failed to allocate buffer: " + std::to_string(vk_result)); } + alloc.buffer = vk::Buffer(vk_buffer); + // 填充分配信息 alloc.info.size = vma_alloc_info.size; alloc.info.offset = vma_alloc_info.offset; - alloc.info.device_memory = vma_alloc_info.deviceMemory; + alloc.info.device_memory = vk::DeviceMemory(vma_alloc_info.deviceMemory); alloc.info.mapped_data = vma_alloc_info.pMappedData; alloc.info.memory_type_index = vma_alloc_info.memoryType; @@ -181,16 +184,16 @@ result gpu_allocator::allocate_image(const image_allocation_in // 创建 Image 信息 VkImageCreateInfo image_info{}; image_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; - image_info.imageType = info.image_type; - image_info.format = info.format; - image_info.extent = info.extent; + image_info.imageType = static_cast(info.image_type); + image_info.format = static_cast(info.format); + image_info.extent = static_cast(info.extent); image_info.mipLevels = info.mip_levels; image_info.arrayLayers = info.array_layers; - image_info.samples = info.samples; - image_info.tiling = info.tiling; - image_info.usage = info.usage; + image_info.samples = static_cast(info.samples); + image_info.tiling = static_cast(info.tiling); + image_info.usage = static_cast(info.usage); image_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; - image_info.initialLayout = info.initial_layout; + image_info.initialLayout = static_cast(info.initial_layout); if (info.is_cube) { image_info.flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT; @@ -203,30 +206,33 @@ result gpu_allocator::allocate_image(const image_allocation_in // Image 通常不需要持久映射 if (info.mem_usage == memory_usage::cpu_only || info.mem_usage == memory_usage::cpu_to_gpu) { // 对于线性平铺的 Image 可能需要映射 - if (info.tiling == VK_IMAGE_TILING_LINEAR) { + if (info.tiling == vk::ImageTiling::eLinear) { alloc_info.flags |= VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT; } } // 执行分配 VmaAllocationInfo vma_alloc_info{}; - VkResult result; + VkResult vk_result; + VkImage vk_image = VK_NULL_HANDLE; { std::lock_guard lock(mutex_); - result = vmaCreateImage(allocator_, &image_info, &alloc_info, - &alloc.image, &alloc.allocation, &vma_alloc_info); + vk_result = vmaCreateImage(allocator_, &image_info, &alloc_info, + &vk_image, &alloc.allocation, &vma_alloc_info); } - if (result != VK_SUCCESS) { + if (vk_result != VK_SUCCESS) { return make_error(error_code::out_of_memory, - "Failed to allocate image: " + std::to_string(result)); + "Failed to allocate image: " + std::to_string(vk_result)); } + alloc.image = vk::Image(vk_image); + // 填充分配信息 alloc.info.size = vma_alloc_info.size; alloc.info.offset = vma_alloc_info.offset; - alloc.info.device_memory = vma_alloc_info.deviceMemory; + alloc.info.device_memory = vk::DeviceMemory(vma_alloc_info.deviceMemory); alloc.info.mapped_data = vma_alloc_info.pMappedData; alloc.info.memory_type_index = vma_alloc_info.memoryType; @@ -253,7 +259,7 @@ void gpu_allocator::free(const image_allocation& alloc) { { std::lock_guard lock(mutex_); - vmaDestroyImage(allocator_, alloc.image, alloc.allocation); + vmaDestroyImage(allocator_, static_cast(alloc.image), alloc.allocation); } // 更新统计 @@ -392,7 +398,7 @@ allocation_info gpu_allocator::get_allocation_info(const buffer_allocation& allo allocation_info info; info.size = vma_info.size; info.offset = vma_info.offset; - info.device_memory = vma_info.deviceMemory; + info.device_memory = vk::DeviceMemory(vma_info.deviceMemory); info.mapped_data = vma_info.pMappedData; info.memory_type_index = vma_info.memoryType; @@ -410,7 +416,7 @@ allocation_info gpu_allocator::get_allocation_info(const image_allocation& alloc allocation_info info; info.size = vma_info.size; info.offset = vma_info.offset; - info.device_memory = vma_info.deviceMemory; + info.device_memory = vk::DeviceMemory(vma_info.deviceMemory); info.mapped_data = vma_info.pMappedData; info.memory_type_index = vma_info.memoryType; @@ -422,8 +428,7 @@ std::vector gpu_allocator::get_memory_budget() const { vmaGetHeapBudgets(allocator_, budgets); // 获取内存堆数量 - VkPhysicalDeviceMemoryProperties mem_props; - vkGetPhysicalDeviceMemoryProperties(physical_device_, &mem_props); + vk::PhysicalDeviceMemoryProperties mem_props = physical_device_.getMemoryProperties(); std::vector result; result.reserve(mem_props.memoryHeapCount); @@ -506,9 +511,9 @@ void gpu_allocator::end_defragmentation() { vmaEndDefragmentation(allocator_, defrag_context_, nullptr); } - defrag_context_ = VK_NULL_HANDLE; + defrag_context_ = nullptr; - log_info("Defragmentation completed"); + MILAI_LOG_INFO("Defragmentation completed"); } bool gpu_allocator::needs_defragmentation(f32 fragmentation_threshold) const { @@ -520,16 +525,15 @@ bool gpu_allocator::needs_defragmentation(f32 fragmentation_threshold) const { // 设备地址 // ================================================================================================ -VkDeviceAddress gpu_allocator::get_buffer_device_address(const buffer_allocation& alloc) const { +vk::DeviceAddress gpu_allocator::get_buffer_device_address(const buffer_allocation& alloc) const { if (!alloc.is_valid() || !enable_buffer_device_address_) { return 0; } - VkBufferDeviceAddressInfo address_info{}; - address_info.sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO; + vk::BufferDeviceAddressInfo address_info{}; address_info.buffer = alloc.buffer; - return vkGetBufferDeviceAddress(device_, &address_info); + return device_.getBufferAddress(address_info); } // ================================================================================================ @@ -537,11 +541,11 @@ VkDeviceAddress gpu_allocator::get_buffer_device_address(const buffer_allocation // ================================================================================================ void gpu_allocator::on_created() { - log_debug("GPU allocator created"); + MILAI_LOG_DEBUG("GPU allocator created"); } void gpu_allocator::on_destroying() { - log_debug("GPU allocator destroying"); + MILAI_LOG_DEBUG("GPU allocator destroying"); } // ================================================================================================ diff --git a/src/resource/allocator.hpp b/src/resource/allocator.hpp index e6a05de..5fce176 100644 --- a/src/resource/allocator.hpp +++ b/src/resource/allocator.hpp @@ -15,8 +15,8 @@ #include "resource_types.hpp" #include "object.hpp" +#include "vulkan_types.hpp" -#include #include #include @@ -47,7 +47,7 @@ struct allocation_info { /// 分配的偏移量 u64 offset = 0; /// 设备内存句柄 - VkDeviceMemory device_memory = VK_NULL_HANDLE; + vk::DeviceMemory device_memory{}; /// 映射的指针(如果已映射) void* mapped_data = nullptr; /// 内存类型索引 @@ -81,14 +81,14 @@ struct buffer_allocation_info { */ struct buffer_allocation { /// Vulkan Buffer 句柄 - VkBuffer buffer = VK_NULL_HANDLE; + vk::Buffer buffer{}; /// VMA 分配句柄 VmaAllocation allocation = VK_NULL_HANDLE; /// 分配信息 allocation_info info; /// 是否有效 [[nodiscard]] bool is_valid() const noexcept { - return buffer != VK_NULL_HANDLE && allocation != VK_NULL_HANDLE; + return buffer && allocation != VK_NULL_HANDLE; } }; @@ -101,23 +101,23 @@ struct buffer_allocation { */ struct image_allocation_info { /// 图像类型 - VkImageType image_type = VK_IMAGE_TYPE_2D; + vk::ImageType image_type = vk::ImageType::e2D; /// 图像格式 - VkFormat format = VK_FORMAT_R8G8B8A8_UNORM; + vk::Format format = vk::Format::eR8G8B8A8Unorm; /// 图像范围 - VkExtent3D extent = {1, 1, 1}; + vk::Extent3D extent = {1, 1, 1}; /// Mip 层级数 u32 mip_levels = 1; /// 数组层数 u32 array_layers = 1; /// 采样数 - VkSampleCountFlagBits samples = VK_SAMPLE_COUNT_1_BIT; + vk::SampleCountFlagBits samples = vk::SampleCountFlagBits::e1; /// 平铺方式 - VkImageTiling tiling = VK_IMAGE_TILING_OPTIMAL; + vk::ImageTiling tiling = vk::ImageTiling::eOptimal; /// 图像用途 - VkImageUsageFlags usage = VK_IMAGE_USAGE_SAMPLED_BIT; + vk::ImageUsageFlags usage = vk::ImageUsageFlagBits::eSampled; /// 初始布局 - VkImageLayout initial_layout = VK_IMAGE_LAYOUT_UNDEFINED; + vk::ImageLayout initial_layout = vk::ImageLayout::eUndefined; /// 内存用途 memory_usage mem_usage = memory_usage::gpu_only; /// 是否为立方体贴图 @@ -131,14 +131,14 @@ struct image_allocation_info { */ struct image_allocation { /// Vulkan Image 句柄 - VkImage image = VK_NULL_HANDLE; + vk::Image image{}; /// VMA 分配句柄 VmaAllocation allocation = VK_NULL_HANDLE; /// 分配信息 allocation_info info; /// 是否有效 [[nodiscard]] bool is_valid() const noexcept { - return image != VK_NULL_HANDLE && allocation != VK_NULL_HANDLE; + return image && allocation != VK_NULL_HANDLE; } }; @@ -151,11 +151,11 @@ struct image_allocation { */ struct allocator_config { /// Vulkan 实例 - VkInstance instance = VK_NULL_HANDLE; + vk::Instance instance{}; /// 物理设备 - VkPhysicalDevice physical_device = VK_NULL_HANDLE; + vk::PhysicalDevice physical_device{}; /// 逻辑设备 - VkDevice device = VK_NULL_HANDLE; + vk::Device device{}; /// Vulkan API 版本 u32 vulkan_api_version = VK_API_VERSION_1_3; /// 是否启用 Buffer Device Address @@ -406,7 +406,7 @@ public: * @param alloc Buffer 分配 * @return 设备地址,如果不支持返回 0 */ - [[nodiscard]] VkDeviceAddress get_buffer_device_address(const buffer_allocation& alloc) const; + [[nodiscard]] vk::DeviceAddress get_buffer_device_address(const buffer_allocation& alloc) const; // ============================================================================================ // 原生句柄 @@ -417,7 +417,7 @@ public: * @return 如果有效返回 true */ [[nodiscard]] bool is_valid() const noexcept { - return allocator_ != VK_NULL_HANDLE; + return allocator_ != nullptr; } /** @@ -432,7 +432,7 @@ public: * @brief 获取 Vulkan 设备 * @return Vulkan 设备句柄 */ - [[nodiscard]] VkDevice get_device() const noexcept { + [[nodiscard]] vk::Device get_device() const noexcept { return device_; } @@ -440,7 +440,7 @@ public: * @brief 获取物理设备 * @return 物理设备句柄 */ - [[nodiscard]] VkPhysicalDevice get_physical_device() const noexcept { + [[nodiscard]] vk::PhysicalDevice get_physical_device() const noexcept { return physical_device_; } @@ -480,19 +480,19 @@ private: memory_usage usage, bool persistent_mapped) noexcept; /// Vulkan 实例 - VkInstance instance_ = VK_NULL_HANDLE; + vk::Instance instance_{}; /// 物理设备 - VkPhysicalDevice physical_device_ = VK_NULL_HANDLE; + vk::PhysicalDevice physical_device_{}; /// 逻辑设备 - VkDevice device_ = VK_NULL_HANDLE; + vk::Device device_{}; /// VMA 分配器 - VmaAllocator allocator_ = VK_NULL_HANDLE; + VmaAllocator allocator_ = nullptr; /// 碎片整理上下文 - VmaDefragmentationContext defrag_context_ = VK_NULL_HANDLE; + VmaDefragmentationContext defrag_context_ = nullptr; /// 是否启用 Buffer Device Address bool enable_buffer_device_address_ = true; diff --git a/src/resource/buffer.cpp b/src/resource/buffer.cpp index a62153c..6cb9c8f 100644 --- a/src/resource/buffer.cpp +++ b/src/resource/buffer.cpp @@ -26,7 +26,7 @@ buffer::buffer(std::shared_ptr allocator, const buffer_create_inf , debug_name_(info.debug_name) { if (!allocator_) { - log_error("Buffer created with null allocator"); + MILAI_LOG_ERROR("Buffer created with null allocator"); return; } @@ -41,7 +41,7 @@ buffer::buffer(std::shared_ptr allocator, const buffer_create_inf // 分配 Buffer auto result = allocator_->allocate_buffer(alloc_info); if (!result.has_value()) { - log_error("Failed to allocate buffer: {}", result.error().message); + MILAI_LOG_ERROR("Failed to allocate buffer: {}", result.error().message); return; } @@ -71,13 +71,13 @@ buffer::buffer(std::shared_ptr allocator, u64 size, , mem_usage_(mem_usage) { if (!allocator_) { - log_error("Buffer created with null allocator"); + MILAI_LOG_ERROR("Buffer created with null allocator"); return; } auto result = allocator_->allocate_buffer(size, usage, mem_usage); if (!result.has_value()) { - log_error("Failed to allocate buffer: {}", result.error().message); + MILAI_LOG_ERROR("Failed to allocate buffer: {}", result.error().message); return; } @@ -263,29 +263,29 @@ void_result buffer::read(void* data, u64 size, u64 offset) { return make_success(); } -void buffer::copy_from(VkCommandBuffer cmd_buffer, const buffer& src_buffer, +void buffer::copy_from(vk::CommandBuffer cmd_buffer, const buffer& src_buffer, u64 src_offset, u64 dst_offset, u64 size) { if (!is_valid() || !src_buffer.is_valid()) { return; } - VkBufferCopy copy_region{}; + vk::BufferCopy copy_region{}; copy_region.srcOffset = src_offset; copy_region.dstOffset = dst_offset; - copy_region.size = (size == VK_WHOLE_SIZE) ? + copy_region.size = (size == VK_WHOLE_SIZE) ? std::min(src_buffer.get_size() - src_offset, size_ - dst_offset) : size; - vkCmdCopyBuffer(cmd_buffer, src_buffer.get_vulkan_buffer(), - allocation_.buffer, 1, ©_region); + cmd_buffer.copyBuffer(src_buffer.get_vulkan_buffer(), + allocation_.buffer, copy_region); } -void buffer::fill(VkCommandBuffer cmd_buffer, u32 value, u64 offset, u64 size) { +void buffer::fill(vk::CommandBuffer cmd_buffer, u32 value, u64 offset, u64 size) { if (!is_valid()) { return; } - vkCmdFillBuffer(cmd_buffer, allocation_.buffer, offset, - (size == VK_WHOLE_SIZE) ? size_ - offset : size, value); + cmd_buffer.fillBuffer(allocation_.buffer, offset, + (size == VK_WHOLE_SIZE) ? size_ - offset : size, value); } // ================================================================================================ @@ -312,7 +312,7 @@ void_result buffer::invalidate(u64 offset, u64 size) { // 设备地址 // ================================================================================================ -VkDeviceAddress buffer::get_device_address() const { +vk::DeviceAddress buffer::get_device_address() const { if (!is_valid() || !allocator_) { return 0; } @@ -324,8 +324,8 @@ VkDeviceAddress buffer::get_device_address() const { // 描述符信息 // ================================================================================================ -VkDescriptorBufferInfo buffer::get_descriptor_info(u64 offset, u64 range) const noexcept { - VkDescriptorBufferInfo info{}; +vk::DescriptorBufferInfo buffer::get_descriptor_info(u64 offset, u64 range) const noexcept { + vk::DescriptorBufferInfo info{}; info.buffer = allocation_.buffer; info.offset = offset; info.range = (range == VK_WHOLE_SIZE) ? size_ - offset : range; @@ -338,13 +338,13 @@ VkDescriptorBufferInfo buffer::get_descriptor_info(u64 offset, u64 range) const void buffer::on_created() { if (!debug_name_.empty()) { - log_debug("Buffer '{}' created: {} bytes", debug_name_, size_); + MILAI_LOG_DEBUG("Buffer '{}' created: {} bytes", debug_name_, size_); } } void buffer::on_destroying() { if (!debug_name_.empty()) { - log_debug("Buffer '{}' destroying", debug_name_); + MILAI_LOG_DEBUG("Buffer '{}' destroying", debug_name_); } } @@ -373,7 +373,7 @@ staging_buffer::staging_buffer(std::shared_ptr allocator, u64 siz , size_(size) { if (!allocator_) { - log_error("Staging buffer created with null allocator"); + MILAI_LOG_ERROR("Staging buffer created with null allocator"); return; } @@ -385,7 +385,7 @@ staging_buffer::staging_buffer(std::shared_ptr allocator, u64 siz auto result = allocator_->allocate_buffer(info); if (!result.has_value()) { - log_error("Failed to allocate staging buffer: {}", result.error().message); + MILAI_LOG_ERROR("Failed to allocate staging buffer: {}", result.error().message); return; } @@ -473,31 +473,30 @@ void_result staging_buffer::read(void* data, u64 size, u64 offset) { return make_success(); } -void staging_buffer::copy_to(VkCommandBuffer cmd_buffer, buffer& dst_buffer, +void staging_buffer::copy_to(vk::CommandBuffer cmd_buffer, buffer& dst_buffer, u64 src_offset, u64 dst_offset, u64 size) { if (!is_valid() || !dst_buffer.is_valid()) { return; } - VkBufferCopy copy_region{}; + vk::BufferCopy copy_region{}; copy_region.srcOffset = src_offset; copy_region.dstOffset = dst_offset; - copy_region.size = (size == VK_WHOLE_SIZE) ? + copy_region.size = (size == VK_WHOLE_SIZE) ? std::min(size_ - src_offset, dst_buffer.get_size() - dst_offset) : size; - vkCmdCopyBuffer(cmd_buffer, allocation_.buffer, - dst_buffer.get_vulkan_buffer(), 1, ©_region); + cmd_buffer.copyBuffer(allocation_.buffer, + dst_buffer.get_vulkan_buffer(), copy_region); } -void staging_buffer::copy_to_image(VkCommandBuffer cmd_buffer, VkImage dst_image, - VkImageLayout dst_layout, - std::span regions) { - if (!is_valid() || dst_image == VK_NULL_HANDLE || regions.empty()) { +void staging_buffer::copy_to_image(vk::CommandBuffer cmd_buffer, vk::Image dst_image, + vk::ImageLayout dst_layout, + std::span regions) { + if (!is_valid() || !dst_image || regions.empty()) { return; } - vkCmdCopyBufferToImage(cmd_buffer, allocation_.buffer, dst_image, dst_layout, - static_cast(regions.size()), regions.data()); + cmd_buffer.copyBufferToImage(allocation_.buffer, dst_image, dst_layout, regions); } void_result staging_buffer::flush() { @@ -509,11 +508,11 @@ void_result staging_buffer::flush() { } void staging_buffer::on_created() { - log_debug("Staging buffer created: {} bytes", size_); + MILAI_LOG_DEBUG("Staging buffer created: {} bytes", size_); } void staging_buffer::on_destroying() { - log_debug("Staging buffer destroying"); + MILAI_LOG_DEBUG("Staging buffer destroying"); } // ================================================================================================ @@ -526,7 +525,7 @@ buffer_pool::buffer_pool(std::shared_ptr allocator, , config_(config) { if (!allocator_) { - log_error("Buffer pool created with null allocator"); + MILAI_LOG_ERROR("Buffer pool created with null allocator"); return; } @@ -549,7 +548,7 @@ buffer_pool::buffer_pool(std::shared_ptr allocator, } } - log_info("Buffer pool created with {} buffers of {} bytes each", + MILAI_LOG_INFO("Buffer pool created with {} buffers of {} bytes each", all_buffers_.size(), config.buffer_size); } @@ -601,11 +600,11 @@ void buffer_pool::reset() { } void buffer_pool::on_created() { - log_debug("Buffer pool created"); + MILAI_LOG_DEBUG("Buffer pool created"); } void buffer_pool::on_destroying() { - log_debug("Buffer pool destroying"); + MILAI_LOG_DEBUG("Buffer pool destroying"); } } // namespace milai \ No newline at end of file diff --git a/src/resource/buffer.hpp b/src/resource/buffer.hpp index 70f73b4..2e5a51c 100644 --- a/src/resource/buffer.hpp +++ b/src/resource/buffer.hpp @@ -16,8 +16,8 @@ #include "resource_types.hpp" #include "allocator.hpp" #include "object.hpp" +#include "vulkan_types.hpp" -#include #include namespace milai { @@ -258,7 +258,7 @@ public: * @param dst_offset 目标偏移量 * @param size 复制大小 */ - void copy_from(VkCommandBuffer cmd_buffer, const buffer& src_buffer, + void copy_from(vk::CommandBuffer cmd_buffer, const buffer& src_buffer, u64 src_offset, u64 dst_offset, u64 size); /** @@ -268,7 +268,7 @@ public: * @param offset 起始偏移量 * @param size 填充大小(VK_WHOLE_SIZE 表示整个 Buffer) */ - void fill(VkCommandBuffer cmd_buffer, u32 value, u64 offset = 0, u64 size = VK_WHOLE_SIZE); + void fill(vk::CommandBuffer cmd_buffer, u32 value, u64 offset = 0, u64 size = VK_WHOLE_SIZE); // ============================================================================================ // 内存同步 @@ -296,9 +296,9 @@ public: /** * @brief 获取 Vulkan Buffer 句柄 - * @return VkBuffer 句柄 + * @return vk::Buffer 句柄 */ - [[nodiscard]] VkBuffer get_vulkan_buffer() const noexcept { + [[nodiscard]] vk::Buffer get_vulkan_buffer() const noexcept { return allocation_.buffer; } @@ -309,7 +309,7 @@ public: * * @return 设备地址,如果不可用返回 0 */ - [[nodiscard]] VkDeviceAddress get_device_address() const; + [[nodiscard]] vk::DeviceAddress get_device_address() const; /** * @brief 获取 VMA 分配 @@ -337,7 +337,7 @@ public: * @param range 范围(VK_WHOLE_SIZE 表示整个 Buffer) * @return VkDescriptorBufferInfo 结构 */ - [[nodiscard]] VkDescriptorBufferInfo get_descriptor_info( + [[nodiscard]] vk::DescriptorBufferInfo get_descriptor_info( u64 offset = 0, u64 range = VK_WHOLE_SIZE) const noexcept; protected: @@ -494,7 +494,7 @@ public: * @param dst_offset 目标偏移量 * @param size 复制大小 */ - void copy_to(VkCommandBuffer cmd_buffer, buffer& dst_buffer, + void copy_to(vk::CommandBuffer cmd_buffer, buffer& dst_buffer, u64 src_offset = 0, u64 dst_offset = 0, u64 size = VK_WHOLE_SIZE); /** @@ -504,15 +504,15 @@ public: * @param dst_layout 目标布局 * @param regions 复制区域 */ - void copy_to_image(VkCommandBuffer cmd_buffer, VkImage dst_image, - VkImageLayout dst_layout, - std::span regions); + void copy_to_image(vk::CommandBuffer cmd_buffer, vk::Image dst_image, + vk::ImageLayout dst_layout, + std::span regions); /** * @brief 获取 Vulkan Buffer 句柄 - * @return VkBuffer 句柄 + * @return vk::Buffer 句柄 */ - [[nodiscard]] VkBuffer get_vulkan_buffer() const noexcept { + [[nodiscard]] vk::Buffer get_vulkan_buffer() const noexcept { return allocation_.buffer; } diff --git a/src/resource/descriptor_pool.cpp b/src/resource/descriptor_pool.cpp index 81d13a9..8323bdb 100644 --- a/src/resource/descriptor_pool.cpp +++ b/src/resource/descriptor_pool.cpp @@ -10,6 +10,7 @@ #include "texture_view.hpp" #include "sampler.hpp" #include "logger.hpp" +#include "vulkan_types.hpp" namespace milai { @@ -17,25 +18,25 @@ namespace milai { // Descriptor Pool 实现 // ================================================================================================ -descriptor_pool::descriptor_pool(VkDevice device, const descriptor_pool_config& config) +descriptor_pool::descriptor_pool(vk::Device device, const descriptor_pool_config& config) : device_(device) , config_(config) { - if (device_ == VK_NULL_HANDLE) { - log_error("Descriptor pool created with null device"); + if (!device_) { + MILAI_LOG_ERROR("Descriptor pool created with null device"); return; } auto result = create_pool(); if (!result.has_value()) { - log_error("Failed to create descriptor pool: {}", result.error().message); + MILAI_LOG_ERROR("Failed to create descriptor pool: {}", result.error().message); } } descriptor_pool::~descriptor_pool() { for (auto pool : pools_) { - if (pool != VK_NULL_HANDLE) { - vkDestroyDescriptorPool(device_, pool, nullptr); + if (pool) { + device_.destroyDescriptorPool(pool); } } pools_.clear(); @@ -48,7 +49,7 @@ descriptor_pool::descriptor_pool(descriptor_pool&& other) noexcept , current_frame_(other.current_frame_) , allocated_sets_(other.allocated_sets_) { - other.device_ = VK_NULL_HANDLE; + other.device_ = vk::Device{}; other.current_frame_ = 0; other.allocated_sets_ = 0; } @@ -57,8 +58,8 @@ descriptor_pool& descriptor_pool::operator=(descriptor_pool&& other) noexcept { if (this != &other) { // 释放当前资源 for (auto pool : pools_) { - if (pool != VK_NULL_HANDLE) { - vkDestroyDescriptorPool(device_, pool, nullptr); + if (pool) { + device_.destroyDescriptorPool(pool); } } @@ -70,7 +71,7 @@ descriptor_pool& descriptor_pool::operator=(descriptor_pool&& other) noexcept { allocated_sets_ = other.allocated_sets_; // 清空源对象 - other.device_ = VK_NULL_HANDLE; + other.device_ = vk::Device{}; other.current_frame_ = 0; other.allocated_sets_ = 0; } @@ -83,24 +84,23 @@ descriptor_pool& descriptor_pool::operator=(descriptor_pool&& other) noexcept { void_result descriptor_pool::create_pool() { // 转换池大小 - std::vector vk_pool_sizes; + std::vector vk_pool_sizes; vk_pool_sizes.reserve(config_.pool_sizes.size()); for (const auto& size : config_.pool_sizes) { - VkDescriptorPoolSize vk_size{}; + vk::DescriptorPoolSize vk_size{}; vk_size.type = to_vulkan_descriptor_type(size.type); vk_size.descriptorCount = size.count; vk_pool_sizes.push_back(vk_size); } - VkDescriptorPoolCreateInfo create_info{}; - create_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; + vk::DescriptorPoolCreateInfo create_info{}; create_info.maxSets = config_.max_sets; create_info.poolSizeCount = static_cast(vk_pool_sizes.size()); create_info.pPoolSizes = vk_pool_sizes.data(); if (config_.allow_free_descriptor_sets) { - create_info.flags |= VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT; + create_info.flags |= vk::DescriptorPoolCreateFlagBits::eFreeDescriptorSet; } // 在 Ring Buffer 模式下创建多个池 @@ -108,11 +108,12 @@ void_result descriptor_pool::create_pool() { pools_.resize(pool_count); for (u32 i = 0; i < pool_count; ++i) { - VkResult result = vkCreateDescriptorPool(device_, &create_info, nullptr, &pools_[i]); - if (result != VK_SUCCESS) { + auto [result, pool] = device_.createDescriptorPool(create_info); + if (result != vk::Result::eSuccess) { return make_void_error(error_code::vulkan_init_failed, - "Failed to create descriptor pool: " + std::to_string(result)); + "Failed to create descriptor pool: " + vk::to_string(result)); } + pools_[i] = pool; } return make_success(); @@ -122,32 +123,30 @@ void_result descriptor_pool::create_pool() { // 描述符集操作 // ================================================================================================ -result> descriptor_pool::allocate(VkDescriptorSetLayout layout) { +result> descriptor_pool::allocate(vk::DescriptorSetLayout layout) { std::lock_guard lock(mutex_); - VkDescriptorSetAllocateInfo alloc_info{}; - alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; + vk::DescriptorSetAllocateInfo alloc_info{}; alloc_info.descriptorPool = get_current_pool(); alloc_info.descriptorSetCount = 1; alloc_info.pSetLayouts = &layout; - VkDescriptorSet set = VK_NULL_HANDLE; - VkResult result = vkAllocateDescriptorSets(device_, &alloc_info, &set); + auto [result, sets] = device_.allocateDescriptorSets(alloc_info); - if (result != VK_SUCCESS) { + if (result != vk::Result::eSuccess) { return make_error>( error_code::out_of_memory, - "Failed to allocate descriptor set: " + std::to_string(result)); + "Failed to allocate descriptor set: " + vk::to_string(result)); } ++allocated_sets_; - auto desc_set = make_obj(this, set, layout); + auto desc_set = make_obj(this, sets[0], layout); return desc_set; } result>> descriptor_pool::allocate( - std::span layouts) { + std::span layouts) { if (layouts.empty()) { return std::vector>{}; @@ -155,19 +154,17 @@ result>> descriptor_pool::allocate( std::lock_guard lock(mutex_); - VkDescriptorSetAllocateInfo alloc_info{}; - alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; + vk::DescriptorSetAllocateInfo alloc_info{}; alloc_info.descriptorPool = get_current_pool(); alloc_info.descriptorSetCount = static_cast(layouts.size()); alloc_info.pSetLayouts = layouts.data(); - std::vector sets(layouts.size()); - VkResult result = vkAllocateDescriptorSets(device_, &alloc_info, sets.data()); + auto [result, sets] = device_.allocateDescriptorSets(alloc_info); - if (result != VK_SUCCESS) { + if (result != vk::Result::eSuccess) { return make_error>>( error_code::out_of_memory, - "Failed to allocate descriptor sets: " + std::to_string(result)); + "Failed to allocate descriptor sets: " + vk::to_string(result)); } allocated_sets_ += static_cast(layouts.size()); @@ -186,8 +183,8 @@ void descriptor_pool::reset() { std::lock_guard lock(mutex_); for (auto pool : pools_) { - if (pool != VK_NULL_HANDLE) { - vkResetDescriptorPool(device_, pool, 0); + if (pool) { + device_.resetDescriptorPool(pool); } } @@ -205,9 +202,9 @@ void descriptor_pool::advance_frame() { current_frame_ = (current_frame_ + 1) % config_.ring_buffer_frames; // 重置下一帧的池 - VkDescriptorPool pool = pools_[current_frame_]; - if (pool != VK_NULL_HANDLE) { - vkResetDescriptorPool(device_, pool, 0); + vk::DescriptorPool pool = pools_[current_frame_]; + if (pool) { + device_.resetDescriptorPool(pool); } } @@ -219,9 +216,9 @@ u32 descriptor_pool::get_available_sets() const noexcept { return config_.max_sets - allocated_sets_; } -VkDescriptorPool descriptor_pool::get_current_pool() const noexcept { +vk::DescriptorPool descriptor_pool::get_current_pool() const noexcept { if (pools_.empty()) { - return VK_NULL_HANDLE; + return vk::DescriptorPool{}; } if (config_.ring_buffer_mode) { @@ -237,14 +234,14 @@ VkDescriptorPool descriptor_pool::get_current_pool() const noexcept { void descriptor_pool::on_created() { if (!config_.debug_name.empty()) { - log_debug("Descriptor pool '{}' created with {} max sets", + MILAI_LOG_DEBUG("Descriptor pool '{}' created with {} max sets", config_.debug_name, config_.max_sets); } } void descriptor_pool::on_destroying() { if (!config_.debug_name.empty()) { - log_debug("Descriptor pool '{}' destroying", config_.debug_name); + MILAI_LOG_DEBUG("Descriptor pool '{}' destroying", config_.debug_name); } } @@ -252,8 +249,8 @@ void descriptor_pool::on_destroying() { // Descriptor Set 实现 // ================================================================================================ -descriptor_set::descriptor_set(descriptor_pool* pool, VkDescriptorSet set, - VkDescriptorSetLayout layout) +descriptor_set::descriptor_set(descriptor_pool* pool, vk::DescriptorSet set, + vk::DescriptorSetLayout layout) : pool_(pool) , set_(set) , layout_(layout) { @@ -269,7 +266,7 @@ descriptor_set::~descriptor_set() { descriptor_set& descriptor_set::bind_buffer(u32 binding, const buffer& buf, u64 offset, u64 range, u32 array_element) { - VkDescriptorBufferInfo buffer_info = buf.get_descriptor_info(offset, range); + vk::DescriptorBufferInfo buffer_info = buf.get_descriptor_info(offset, range); // 根据 buffer 用途确定描述符类型 descriptor_type type = descriptor_type::uniform_buffer; @@ -280,7 +277,7 @@ descriptor_set& descriptor_set::bind_buffer(u32 binding, const buffer& buf, return bind_buffer(binding, buffer_info, type, array_element); } -descriptor_set& descriptor_set::bind_buffer(u32 binding, const VkDescriptorBufferInfo& buffer_info, +descriptor_set& descriptor_set::bind_buffer(u32 binding, const vk::DescriptorBufferInfo& buffer_info, descriptor_type type, u32 array_element) { descriptor_write write; write.binding = binding; @@ -299,14 +296,14 @@ descriptor_set& descriptor_set::bind_texture(u32 binding, const texture_view& vi layout, array_element); } -descriptor_set& descriptor_set::bind_texture(u32 binding, VkImageView view, VkSampler samp, - VkImageLayout layout, u32 array_element) { +descriptor_set& descriptor_set::bind_texture(u32 binding, vk::ImageView view, vk::Sampler samp, + vk::ImageLayout layout, u32 array_element) { descriptor_write write; write.binding = binding; write.array_element = array_element; write.type = descriptor_type::combined_image_sampler; - VkDescriptorImageInfo image_info{}; + vk::DescriptorImageInfo image_info{}; image_info.sampler = samp; image_info.imageView = view; image_info.imageLayout = layout; @@ -317,14 +314,14 @@ descriptor_set& descriptor_set::bind_texture(u32 binding, VkImageView view, VkSa } descriptor_set& descriptor_set::bind_sampled_image(u32 binding, const texture_view& view, - VkImageLayout layout, u32 array_element) { + vk::ImageLayout layout, u32 array_element) { descriptor_write write; write.binding = binding; write.array_element = array_element; write.type = descriptor_type::sampled_image; - VkDescriptorImageInfo image_info{}; - image_info.sampler = VK_NULL_HANDLE; + vk::DescriptorImageInfo image_info{}; + image_info.sampler = vk::Sampler{}; image_info.imageView = view.get_vulkan_view(); image_info.imageLayout = layout; write.image_infos.push_back(image_info); @@ -340,10 +337,10 @@ descriptor_set& descriptor_set::bind_storage_image(u32 binding, const texture_vi write.array_element = array_element; write.type = descriptor_type::storage_image; - VkDescriptorImageInfo image_info{}; - image_info.sampler = VK_NULL_HANDLE; + vk::DescriptorImageInfo image_info{}; + image_info.sampler = vk::Sampler{}; image_info.imageView = view.get_vulkan_view(); - image_info.imageLayout = VK_IMAGE_LAYOUT_GENERAL; + image_info.imageLayout = vk::ImageLayout::eGeneral; write.image_infos.push_back(image_info); pending_writes_.push_back(std::move(write)); @@ -356,10 +353,10 @@ descriptor_set& descriptor_set::bind_sampler(u32 binding, const sampler& samp, u write.array_element = array_element; write.type = descriptor_type::sampler; - VkDescriptorImageInfo image_info{}; + vk::DescriptorImageInfo image_info{}; image_info.sampler = samp.get_vulkan_sampler(); - image_info.imageView = VK_NULL_HANDLE; - image_info.imageLayout = VK_IMAGE_LAYOUT_UNDEFINED; + image_info.imageView = vk::ImageView{}; + image_info.imageLayout = vk::ImageLayout::eUndefined; write.image_infos.push_back(image_info); pending_writes_.push_back(std::move(write)); @@ -367,14 +364,14 @@ descriptor_set& descriptor_set::bind_sampler(u32 binding, const sampler& samp, u } descriptor_set& descriptor_set::bind_input_attachment(u32 binding, const texture_view& view, - VkImageLayout layout, u32 array_element) { + vk::ImageLayout layout, u32 array_element) { descriptor_write write; write.binding = binding; write.array_element = array_element; write.type = descriptor_type::input_attachment; - VkDescriptorImageInfo image_info{}; - image_info.sampler = VK_NULL_HANDLE; + vk::DescriptorImageInfo image_info{}; + image_info.sampler = vk::Sampler{}; image_info.imageView = view.get_vulkan_view(); image_info.imageLayout = layout; write.image_infos.push_back(image_info); @@ -408,13 +405,12 @@ void descriptor_set::update() { buffer_infos_.reserve(total_buffer_infos); image_infos_.reserve(total_image_infos); - // 构建 VkWriteDescriptorSet 数组 - std::vector vk_writes; + // 构建 vk::WriteDescriptorSet 数组 + std::vector vk_writes; vk_writes.reserve(pending_writes_.size()); for (const auto& write : pending_writes_) { - VkWriteDescriptorSet vk_write{}; - vk_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + vk::WriteDescriptorSet vk_write{}; vk_write.dstSet = set_; vk_write.dstBinding = write.binding; vk_write.dstArrayElement = write.array_element; @@ -447,9 +443,7 @@ void descriptor_set::update() { } // 更新描述符 - vkUpdateDescriptorSets(pool_->get_device(), - static_cast(vk_writes.size()), vk_writes.data(), - 0, nullptr); + pool_->get_device().updateDescriptorSets(vk_writes, {}); // 清除待处理写入 pending_writes_.clear(); @@ -464,11 +458,11 @@ void descriptor_set::clear_pending_writes() { // ================================================================================================ void descriptor_set::on_created() { - log_debug("Descriptor set created"); + MILAI_LOG_DEBUG("Descriptor set created"); } void descriptor_set::on_destroying() { - log_debug("Descriptor set destroying"); + MILAI_LOG_DEBUG("Descriptor set destroying"); } } // namespace milai \ No newline at end of file diff --git a/src/resource/descriptor_pool.hpp b/src/resource/descriptor_pool.hpp index 4744915..5851eeb 100644 --- a/src/resource/descriptor_pool.hpp +++ b/src/resource/descriptor_pool.hpp @@ -14,8 +14,8 @@ #include "resource_types.hpp" #include "object.hpp" +#include "vulkan_types.hpp" -#include #include #include #include @@ -118,9 +118,9 @@ struct descriptor_binding_info { /// 描述符数量 u32 count = 1; /// 着色器阶段 - VkShaderStageFlags stages = VK_SHADER_STAGE_ALL; + vk::ShaderStageFlags stages = vk::ShaderStageFlagBits::eAll; /// 不可变采样器(可选) - std::vector immutable_samplers; + std::vector immutable_samplers; }; // ================================================================================================ @@ -138,11 +138,11 @@ struct descriptor_write { /// 描述符类型 descriptor_type type = descriptor_type::uniform_buffer; /// Buffer 信息(用于 buffer 类型) - std::vector buffer_infos; + std::vector buffer_infos; /// Image 信息(用于 image 类型) - std::vector image_infos; + std::vector image_infos; /// Texel buffer view(用于 texel buffer 类型) - std::vector texel_buffer_views; + std::vector texel_buffer_views; }; // ================================================================================================ @@ -183,7 +183,7 @@ public: * @param device Vulkan 设备 * @param config 池配置 */ - descriptor_pool(VkDevice device, const descriptor_pool_config& config); + descriptor_pool(vk::Device device, const descriptor_pool_config& config); /** * @brief 析构函数 @@ -207,7 +207,7 @@ public: * @param layout 描述符集布局 * @return 描述符集 */ - [[nodiscard]] result> allocate(VkDescriptorSetLayout layout); + [[nodiscard]] result> allocate(vk::DescriptorSetLayout layout); /** * @brief 分配多个描述符集 @@ -215,7 +215,7 @@ public: * @return 描述符集列表 */ [[nodiscard]] result>> allocate( - std::span layouts); + std::span layouts); /** * @brief 重置池 @@ -275,9 +275,9 @@ public: /** * @brief 获取 Vulkan 设备 - * @return VkDevice 句柄 + * @return vk::Device 句柄 */ - [[nodiscard]] VkDevice get_device() const noexcept { + [[nodiscard]] vk::Device get_device() const noexcept { return device_; } @@ -296,13 +296,13 @@ private: * @brief 获取当前池 * @return 当前活跃的池 */ - [[nodiscard]] VkDescriptorPool get_current_pool() const noexcept; + [[nodiscard]] vk::DescriptorPool get_current_pool() const noexcept; /// Vulkan 设备 - VkDevice device_ = VK_NULL_HANDLE; + vk::Device device_; /// 描述符池列表(Ring Buffer 模式下每帧一个) - std::vector pools_; + std::vector pools_; /// 配置 descriptor_pool_config config_; @@ -351,7 +351,7 @@ public: * @param set Vulkan 描述符集 * @param layout 描述符集布局 */ - descriptor_set(descriptor_pool* pool, VkDescriptorSet set, VkDescriptorSetLayout layout); + descriptor_set(descriptor_pool* pool, vk::DescriptorSet set, vk::DescriptorSetLayout layout); /** * @brief 析构函数 @@ -382,14 +382,14 @@ public: u32 array_element = 0); /** - * @brief 绑定 Buffer(使用 VkDescriptorBufferInfo) + * @brief 绑定 Buffer(使用 vk::DescriptorBufferInfo) * @param binding 绑定点 * @param buffer_info Buffer 信息 * @param type 描述符类型 * @param array_element 数组元素索引 * @return 自身引用 */ - descriptor_set& bind_buffer(u32 binding, const VkDescriptorBufferInfo& buffer_info, + descriptor_set& bind_buffer(u32 binding, const vk::DescriptorBufferInfo& buffer_info, descriptor_type type = descriptor_type::uniform_buffer, u32 array_element = 0); @@ -403,20 +403,20 @@ public: * @return 自身引用 */ descriptor_set& bind_texture(u32 binding, const texture_view& view, const sampler& samp, - VkImageLayout layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + vk::ImageLayout layout = vk::ImageLayout::eShaderReadOnlyOptimal, u32 array_element = 0); /** * @brief 绑定纹理(使用 Vulkan 句柄) * @param binding 绑定点 - * @param view VkImageView - * @param samp VkSampler + * @param view vk::ImageView + * @param samp vk::Sampler * @param layout 图像布局 * @param array_element 数组元素索引 * @return 自身引用 */ - descriptor_set& bind_texture(u32 binding, VkImageView view, VkSampler samp, - VkImageLayout layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + descriptor_set& bind_texture(u32 binding, vk::ImageView view, vk::Sampler samp, + vk::ImageLayout layout = vk::ImageLayout::eShaderReadOnlyOptimal, u32 array_element = 0); /** @@ -428,7 +428,7 @@ public: * @return 自身引用 */ descriptor_set& bind_sampled_image(u32 binding, const texture_view& view, - VkImageLayout layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + vk::ImageLayout layout = vk::ImageLayout::eShaderReadOnlyOptimal, u32 array_element = 0); /** @@ -459,7 +459,7 @@ public: * @return 自身引用 */ descriptor_set& bind_input_attachment(u32 binding, const texture_view& view, - VkImageLayout layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + vk::ImageLayout layout = vk::ImageLayout::eShaderReadOnlyOptimal, u32 array_element = 0); // ============================================================================================ @@ -492,17 +492,17 @@ public: /** * @brief 获取 Vulkan 描述符集句柄 - * @return VkDescriptorSet 句柄 + * @return vk::DescriptorSet 句柄 */ - [[nodiscard]] VkDescriptorSet get_vulkan_set() const noexcept { + [[nodiscard]] vk::DescriptorSet get_vulkan_set() const noexcept { return set_; } /** * @brief 获取描述符集布局 - * @return VkDescriptorSetLayout 句柄 + * @return vk::DescriptorSetLayout 句柄 */ - [[nodiscard]] VkDescriptorSetLayout get_layout() const noexcept { + [[nodiscard]] vk::DescriptorSetLayout get_layout() const noexcept { return layout_; } @@ -511,7 +511,7 @@ public: * @return 如果有效返回 true */ [[nodiscard]] bool is_valid() const noexcept { - return set_ != VK_NULL_HANDLE; + return set_; } protected: @@ -522,20 +522,20 @@ private: /// 所属描述符池 descriptor_pool* pool_ = nullptr; - /// VkDescriptorSet 句柄 - VkDescriptorSet set_ = VK_NULL_HANDLE; + /// vk::DescriptorSet 句柄 + vk::DescriptorSet set_; /// 描述符集布局 - VkDescriptorSetLayout layout_ = VK_NULL_HANDLE; + vk::DescriptorSetLayout layout_; /// 待处理的写入 std::vector pending_writes_; /// Buffer 信息存储(防止悬空指针) - std::vector buffer_infos_; + std::vector buffer_infos_; /// Image 信息存储 - std::vector image_infos_; + std::vector image_infos_; }; } // namespace milai \ No newline at end of file diff --git a/src/resource/resource_loader.cpp b/src/resource/resource_loader.cpp index aff2990..fbdda9b 100644 --- a/src/resource/resource_loader.cpp +++ b/src/resource/resource_loader.cpp @@ -33,7 +33,7 @@ resource_loader::resource_loader(std::shared_ptr allocator, , queue_family_index_(queue_family_index) { if (!allocator_ || device_ == VK_NULL_HANDLE || queue_ == VK_NULL_HANDLE) { - log_error("Resource loader created with invalid parameters"); + MILAI_LOG_ERROR("Resource loader created with invalid parameters"); return; } @@ -45,7 +45,7 @@ resource_loader::resource_loader(std::shared_ptr allocator, VkResult result = vkCreateCommandPool(device_, &pool_info, nullptr, &command_pool_); if (result != VK_SUCCESS) { - log_error("Failed to create command pool for resource loader: {}", static_cast(result)); + MILAI_LOG_ERROR("Failed to create command pool for resource loader: {}", static_cast(result)); return; } @@ -55,7 +55,7 @@ resource_loader::resource_loader(std::shared_ptr allocator, result = vkCreateFence(device_, &fence_info, nullptr, &fence_); if (result != VK_SUCCESS) { - log_error("Failed to create fence for resource loader: {}", static_cast(result)); + MILAI_LOG_ERROR("Failed to create fence for resource loader: {}", static_cast(result)); return; } @@ -611,7 +611,7 @@ std::vector resource_loader::load_image_from_file( &width, &height, &channels, req_channels); if (!pixels) { - log_error("Failed to decode image: {}", stbi_failure_reason()); + MILAI_LOG_ERROR("Failed to decode image: {}", stbi_failure_reason()); return {}; } @@ -628,7 +628,7 @@ std::vector resource_loader::load_image_from_file( std::vector resource_loader::load_binary_from_file(const std::filesystem::path& path) { std::ifstream file(path, std::ios::binary | std::ios::ate); if (!file.is_open()) { - log_error("Failed to open file: {}", path.string()); + MILAI_LOG_ERROR("Failed to open file: {}", path.string()); return {}; } @@ -641,7 +641,7 @@ std::vector resource_loader::load_binary_from_file(const std::filesystem::pa std::vector data(static_cast(size)); if (!file.read(reinterpret_cast(data.data()), size)) { - log_error("Failed to read file: {}", path.string()); + MILAI_LOG_ERROR("Failed to read file: {}", path.string()); return {}; } @@ -687,11 +687,11 @@ void resource_loader::submit_and_wait(VkCommandBuffer cmd_buffer) { // ================================================================================================ void resource_loader::on_created() { - log_info("Resource loader created"); + MILAI_LOG_INFO("Resource loader created"); } void resource_loader::on_destroying() { - log_info("Resource loader destroying"); + MILAI_LOG_INFO("Resource loader destroying"); } } // namespace milai \ No newline at end of file diff --git a/src/resource/resource_manager.cpp b/src/resource/resource_manager.cpp index f41c84f..2f55996 100644 --- a/src/resource/resource_manager.cpp +++ b/src/resource/resource_manager.cpp @@ -82,7 +82,7 @@ resource_manager::resource_manager(VkInstance instance, if (instance_ == VK_NULL_HANDLE || device_ == VK_NULL_HANDLE || physical_device_ == VK_NULL_HANDLE || queue_ == VK_NULL_HANDLE) { - log_error("Resource manager created with invalid Vulkan handles"); + MILAI_LOG_ERROR("Resource manager created with invalid Vulkan handles"); return; } @@ -93,7 +93,7 @@ resource_manager::resource_manager(VkInstance instance, alloc_config.device = device_; allocator_ = std::make_shared(alloc_config); if (!allocator_->is_valid()) { - log_error("Failed to create GPU allocator"); + MILAI_LOG_ERROR("Failed to create GPU allocator"); return; } @@ -159,13 +159,13 @@ object_ptr resource_manager::create_buffer(u64 size, object_ptr resource_manager::create_buffer(const buffer_create_info& info) { if (!is_valid()) { - log_error("Resource manager is not valid"); + MILAI_LOG_ERROR("Resource manager is not valid"); return nullptr; } auto buf = make_obj(allocator_, info); if (!buf || !buf->is_valid()) { - log_error("Failed to create buffer: {}", info.debug_name); + MILAI_LOG_ERROR("Failed to create buffer: {}", info.debug_name); return nullptr; } @@ -175,7 +175,7 @@ object_ptr resource_manager::create_buffer(const buffer_create_info& inf buffer_count_.fetch_add(1, std::memory_order_relaxed); - log_debug("Created buffer '{}': {} bytes, usage={}", + MILAI_LOG_DEBUG("Created buffer '{}': {} bytes, usage={}", info.debug_name, info.size, static_cast(info.usage)); return buf; @@ -212,13 +212,13 @@ object_ptr resource_manager::create_staging_buffer(u64 size, const std:: object_ptr resource_manager::create_texture(const texture_info& info) { if (!is_valid()) { - log_error("Resource manager is not valid"); + MILAI_LOG_ERROR("Resource manager is not valid"); return nullptr; } auto tex = make_obj(allocator_, info); if (!tex || !tex->is_valid()) { - log_error("Failed to create texture: {}", info.debug_name); + MILAI_LOG_ERROR("Failed to create texture: {}", info.debug_name); return nullptr; } @@ -228,7 +228,7 @@ object_ptr resource_manager::create_texture(const texture_info& info) { texture_count_.fetch_add(1, std::memory_order_relaxed); - log_debug("Created texture '{}': {}x{}x{}, format={}", + MILAI_LOG_DEBUG("Created texture '{}': {}x{}x{}, format={}", info.debug_name, info.width, info.height, info.depth, static_cast(info.format)); @@ -313,13 +313,13 @@ object_ptr resource_manager::create_texture_view(object_ptris_valid()) { - log_error("Invalid resource manager or texture"); + MILAI_LOG_ERROR("Invalid resource manager or texture"); return nullptr; } auto view_result = tex->create_view(aspect, base_mip, mip_count, base_layer, layer_count); if (!view_result.has_value()) { - log_error("Failed to create texture view: {}", view_result.error().message); + MILAI_LOG_ERROR("Failed to create texture view: {}", view_result.error().message); return nullptr; } @@ -341,13 +341,13 @@ object_ptr resource_manager::create_texture_view(object_ptr resource_manager::create_default_view(object_ptr tex, const std::string& debug_name) { if (!is_valid() || !tex || !tex->is_valid()) { - log_error("Invalid resource manager or texture"); + MILAI_LOG_ERROR("Invalid resource manager or texture"); return nullptr; } auto view_result = tex->create_default_view(); if (!view_result.has_value()) { - log_error("Failed to create default texture view: {}", view_result.error().message); + MILAI_LOG_ERROR("Failed to create default texture view: {}", view_result.error().message); return nullptr; } @@ -372,13 +372,13 @@ object_ptr resource_manager::create_default_view(object_ptr resource_manager::create_sampler(const sampler_info& info) { if (!is_valid()) { - log_error("Resource manager is not valid"); + MILAI_LOG_ERROR("Resource manager is not valid"); return nullptr; } auto samp = make_obj(device_, info); if (!samp || !samp->is_valid()) { - log_error("Failed to create sampler"); + MILAI_LOG_ERROR("Failed to create sampler"); return nullptr; } @@ -411,13 +411,13 @@ object_ptr resource_manager::get_preset_sampler(sampler_preset preset) object_ptr resource_manager::create_descriptor_pool(const descriptor_pool_config& config) { if (!is_valid()) { - log_error("Resource manager is not valid"); + MILAI_LOG_ERROR("Resource manager is not valid"); return nullptr; } auto pool = make_obj(device_, config); if (!pool || !pool->is_valid()) { - log_error("Failed to create descriptor pool"); + MILAI_LOG_ERROR("Failed to create descriptor pool"); return nullptr; } @@ -717,11 +717,11 @@ bool resource_manager::is_valid() const { // ================================================================================================ void resource_manager::on_created() { - log_info("Resource manager created"); + MILAI_LOG_INFO("Resource manager created"); } void resource_manager::on_destroying() { - log_info("Resource manager destroying"); + MILAI_LOG_INFO("Resource manager destroying"); } // ================================================================================================ diff --git a/src/resource/resource_types.hpp b/src/resource/resource_types.hpp index 889ffde..3791b2e 100644 --- a/src/resource/resource_types.hpp +++ b/src/resource/resource_types.hpp @@ -15,9 +15,9 @@ #pragma once +#include "flag_enum.hpp" #include "types.hpp" - -#include +#include "vulkan_types.hpp" namespace milai { @@ -52,82 +52,42 @@ enum class buffer_usage : u32 { /// 着色器设备地址 shader_device_address = 1 << 8, }; +MILAI_ENABLE_FLAG_ENUM(buffer_usage); /** - * @brief 按位或运算符 - * @param lhs 左操作数 - * @param rhs 右操作数 - * @return 组合后的 buffer_usage - */ -[[nodiscard]] constexpr buffer_usage operator|(buffer_usage lhs, buffer_usage rhs) noexcept { - return static_cast(static_cast(lhs) | static_cast(rhs)); -} - -/** - * @brief 按位与运算符 - * @param lhs 左操作数 - * @param rhs 右操作数 - * @return 组合后的 buffer_usage - */ -[[nodiscard]] constexpr buffer_usage operator&(buffer_usage lhs, buffer_usage rhs) noexcept { - return static_cast(static_cast(lhs) & static_cast(rhs)); -} - -/** - * @brief 按位或赋值运算符 - * @param lhs 左操作数 - * @param rhs 右操作数 - * @return 组合后的 buffer_usage 引用 - */ -constexpr buffer_usage& operator|=(buffer_usage& lhs, buffer_usage rhs) noexcept { - lhs = lhs | rhs; - return lhs; -} - -/** - * @brief 检查 buffer_usage 是否包含指定标志 - * @param usage 要检查的用途 - * @param flag 要检查的标志 - * @return 如果包含返回 true - */ -[[nodiscard]] constexpr bool has_flag(buffer_usage usage, buffer_usage flag) noexcept { - return (static_cast(usage) & static_cast(flag)) != 0; -} - -/** - * @brief 将 buffer_usage 转换为 VkBufferUsageFlags + * @brief 将 buffer_usage 转换为 vk::BufferUsageFlags * @param usage buffer 用途 * @return Vulkan buffer 用途标志 */ -[[nodiscard]] constexpr VkBufferUsageFlags to_vulkan_buffer_usage(buffer_usage usage) noexcept { - VkBufferUsageFlags flags = 0; +[[nodiscard]] constexpr vk::BufferUsageFlags to_vulkan_buffer_usage(buffer_usage usage) noexcept { + vk::BufferUsageFlags flags{}; if (has_flag(usage, buffer_usage::vertex)) { - flags |= VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; + flags |= vk::BufferUsageFlagBits::eVertexBuffer; } if (has_flag(usage, buffer_usage::index)) { - flags |= VK_BUFFER_USAGE_INDEX_BUFFER_BIT; + flags |= vk::BufferUsageFlagBits::eIndexBuffer; } if (has_flag(usage, buffer_usage::uniform)) { - flags |= VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; + flags |= vk::BufferUsageFlagBits::eUniformBuffer; } if (has_flag(usage, buffer_usage::storage)) { - flags |= VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; + flags |= vk::BufferUsageFlagBits::eStorageBuffer; } if (has_flag(usage, buffer_usage::indirect)) { - flags |= VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT; + flags |= vk::BufferUsageFlagBits::eIndirectBuffer; } if (has_flag(usage, buffer_usage::transfer_src)) { - flags |= VK_BUFFER_USAGE_TRANSFER_SRC_BIT; + flags |= vk::BufferUsageFlagBits::eTransferSrc; } if (has_flag(usage, buffer_usage::transfer_dst)) { - flags |= VK_BUFFER_USAGE_TRANSFER_DST_BIT; + flags |= vk::BufferUsageFlagBits::eTransferDst; } if (has_flag(usage, buffer_usage::shader_device_address)) { - flags |= VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT; + flags |= vk::BufferUsageFlagBits::eShaderDeviceAddress; } if (has_flag(usage, buffer_usage::staging)) { - flags |= VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; + flags |= vk::BufferUsageFlagBits::eTransferSrc | vk::BufferUsageFlagBits::eTransferDst; } return flags; @@ -330,196 +290,196 @@ enum class texture_format : u32 { }; /** - * @brief 将 texture_format 转换为 VkFormat + * @brief 将 texture_format 转换为 vk::Format * @param format 纹理格式 * @return Vulkan 格式 */ -[[nodiscard]] constexpr VkFormat to_vulkan_format(texture_format format) noexcept { +[[nodiscard]] constexpr vk::Format to_vulkan_format(texture_format format) noexcept { switch (format) { - case texture_format::undefined: return VK_FORMAT_UNDEFINED; + case texture_format::undefined: return vk::Format::eUndefined; // 8位格式 - case texture_format::r8_unorm: return VK_FORMAT_R8_UNORM; - case texture_format::r8_snorm: return VK_FORMAT_R8_SNORM; - case texture_format::r8_uint: return VK_FORMAT_R8_UINT; - case texture_format::r8_sint: return VK_FORMAT_R8_SINT; + case texture_format::r8_unorm: return vk::Format::eR8Unorm; + case texture_format::r8_snorm: return vk::Format::eR8Snorm; + case texture_format::r8_uint: return vk::Format::eR8Uint; + case texture_format::r8_sint: return vk::Format::eR8Sint; - case texture_format::rg8_unorm: return VK_FORMAT_R8G8_UNORM; - case texture_format::rg8_snorm: return VK_FORMAT_R8G8_SNORM; - case texture_format::rg8_uint: return VK_FORMAT_R8G8_UINT; - case texture_format::rg8_sint: return VK_FORMAT_R8G8_SINT; + case texture_format::rg8_unorm: return vk::Format::eR8G8Unorm; + case texture_format::rg8_snorm: return vk::Format::eR8G8Snorm; + case texture_format::rg8_uint: return vk::Format::eR8G8Uint; + case texture_format::rg8_sint: return vk::Format::eR8G8Sint; - case texture_format::rgba8_unorm: return VK_FORMAT_R8G8B8A8_UNORM; - case texture_format::rgba8_srgb: return VK_FORMAT_R8G8B8A8_SRGB; - case texture_format::rgba8_snorm: return VK_FORMAT_R8G8B8A8_SNORM; - case texture_format::rgba8_uint: return VK_FORMAT_R8G8B8A8_UINT; - case texture_format::rgba8_sint: return VK_FORMAT_R8G8B8A8_SINT; + case texture_format::rgba8_unorm: return vk::Format::eR8G8B8A8Unorm; + case texture_format::rgba8_srgb: return vk::Format::eR8G8B8A8Srgb; + case texture_format::rgba8_snorm: return vk::Format::eR8G8B8A8Snorm; + case texture_format::rgba8_uint: return vk::Format::eR8G8B8A8Uint; + case texture_format::rgba8_sint: return vk::Format::eR8G8B8A8Sint; - case texture_format::bgra8_unorm: return VK_FORMAT_B8G8R8A8_UNORM; - case texture_format::bgra8_srgb: return VK_FORMAT_B8G8R8A8_SRGB; + case texture_format::bgra8_unorm: return vk::Format::eB8G8R8A8Unorm; + case texture_format::bgra8_srgb: return vk::Format::eB8G8R8A8Srgb; // 16位格式 - case texture_format::r16_float: return VK_FORMAT_R16_SFLOAT; - case texture_format::r16_unorm: return VK_FORMAT_R16_UNORM; - case texture_format::r16_snorm: return VK_FORMAT_R16_SNORM; - case texture_format::r16_uint: return VK_FORMAT_R16_UINT; - case texture_format::r16_sint: return VK_FORMAT_R16_SINT; + case texture_format::r16_float: return vk::Format::eR16Sfloat; + case texture_format::r16_unorm: return vk::Format::eR16Unorm; + case texture_format::r16_snorm: return vk::Format::eR16Snorm; + case texture_format::r16_uint: return vk::Format::eR16Uint; + case texture_format::r16_sint: return vk::Format::eR16Sint; - case texture_format::rg16_float: return VK_FORMAT_R16G16_SFLOAT; - case texture_format::rg16_unorm: return VK_FORMAT_R16G16_UNORM; - case texture_format::rg16_snorm: return VK_FORMAT_R16G16_SNORM; - case texture_format::rg16_uint: return VK_FORMAT_R16G16_UINT; - case texture_format::rg16_sint: return VK_FORMAT_R16G16_SINT; + case texture_format::rg16_float: return vk::Format::eR16G16Sfloat; + case texture_format::rg16_unorm: return vk::Format::eR16G16Unorm; + case texture_format::rg16_snorm: return vk::Format::eR16G16Snorm; + case texture_format::rg16_uint: return vk::Format::eR16G16Uint; + case texture_format::rg16_sint: return vk::Format::eR16G16Sint; - case texture_format::rgba16_float: return VK_FORMAT_R16G16B16A16_SFLOAT; - case texture_format::rgba16_unorm: return VK_FORMAT_R16G16B16A16_UNORM; - case texture_format::rgba16_snorm: return VK_FORMAT_R16G16B16A16_SNORM; - case texture_format::rgba16_uint: return VK_FORMAT_R16G16B16A16_UINT; - case texture_format::rgba16_sint: return VK_FORMAT_R16G16B16A16_SINT; + case texture_format::rgba16_float: return vk::Format::eR16G16B16A16Sfloat; + case texture_format::rgba16_unorm: return vk::Format::eR16G16B16A16Unorm; + case texture_format::rgba16_snorm: return vk::Format::eR16G16B16A16Snorm; + case texture_format::rgba16_uint: return vk::Format::eR16G16B16A16Uint; + case texture_format::rgba16_sint: return vk::Format::eR16G16B16A16Sint; // 32位格式 - case texture_format::r32_float: return VK_FORMAT_R32_SFLOAT; - case texture_format::r32_uint: return VK_FORMAT_R32_UINT; - case texture_format::r32_sint: return VK_FORMAT_R32_SINT; + case texture_format::r32_float: return vk::Format::eR32Sfloat; + case texture_format::r32_uint: return vk::Format::eR32Uint; + case texture_format::r32_sint: return vk::Format::eR32Sint; - case texture_format::rg32_float: return VK_FORMAT_R32G32_SFLOAT; - case texture_format::rg32_uint: return VK_FORMAT_R32G32_UINT; - case texture_format::rg32_sint: return VK_FORMAT_R32G32_SINT; + case texture_format::rg32_float: return vk::Format::eR32G32Sfloat; + case texture_format::rg32_uint: return vk::Format::eR32G32Uint; + case texture_format::rg32_sint: return vk::Format::eR32G32Sint; - case texture_format::rgb32_float: return VK_FORMAT_R32G32B32_SFLOAT; - case texture_format::rgb32_uint: return VK_FORMAT_R32G32B32_UINT; - case texture_format::rgb32_sint: return VK_FORMAT_R32G32B32_SINT; + case texture_format::rgb32_float: return vk::Format::eR32G32B32Sfloat; + case texture_format::rgb32_uint: return vk::Format::eR32G32B32Uint; + case texture_format::rgb32_sint: return vk::Format::eR32G32B32Sint; - case texture_format::rgba32_float: return VK_FORMAT_R32G32B32A32_SFLOAT; - case texture_format::rgba32_uint: return VK_FORMAT_R32G32B32A32_UINT; - case texture_format::rgba32_sint: return VK_FORMAT_R32G32B32A32_SINT; + case texture_format::rgba32_float: return vk::Format::eR32G32B32A32Sfloat; + case texture_format::rgba32_uint: return vk::Format::eR32G32B32A32Uint; + case texture_format::rgba32_sint: return vk::Format::eR32G32B32A32Sint; // 深度/模板格式 - case texture_format::depth16_unorm: return VK_FORMAT_D16_UNORM; - case texture_format::depth24_unorm: return VK_FORMAT_X8_D24_UNORM_PACK32; - case texture_format::depth32_float: return VK_FORMAT_D32_SFLOAT; - case texture_format::depth24_unorm_stencil8_uint: return VK_FORMAT_D24_UNORM_S8_UINT; - case texture_format::depth32_float_stencil8_uint: return VK_FORMAT_D32_SFLOAT_S8_UINT; - case texture_format::stencil8_uint: return VK_FORMAT_S8_UINT; + case texture_format::depth16_unorm: return vk::Format::eD16Unorm; + case texture_format::depth24_unorm: return vk::Format::eX8D24UnormPack32; + case texture_format::depth32_float: return vk::Format::eD32Sfloat; + case texture_format::depth24_unorm_stencil8_uint: return vk::Format::eD24UnormS8Uint; + case texture_format::depth32_float_stencil8_uint: return vk::Format::eD32SfloatS8Uint; + case texture_format::stencil8_uint: return vk::Format::eS8Uint; // 压缩格式 - case texture_format::bc1_rgb_unorm: return VK_FORMAT_BC1_RGB_UNORM_BLOCK; - case texture_format::bc1_rgb_srgb: return VK_FORMAT_BC1_RGB_SRGB_BLOCK; - case texture_format::bc1_rgba_unorm: return VK_FORMAT_BC1_RGBA_UNORM_BLOCK; - case texture_format::bc1_rgba_srgb: return VK_FORMAT_BC1_RGBA_SRGB_BLOCK; - case texture_format::bc2_unorm: return VK_FORMAT_BC2_UNORM_BLOCK; - case texture_format::bc2_srgb: return VK_FORMAT_BC2_SRGB_BLOCK; - case texture_format::bc3_unorm: return VK_FORMAT_BC3_UNORM_BLOCK; - case texture_format::bc3_srgb: return VK_FORMAT_BC3_SRGB_BLOCK; - case texture_format::bc4_unorm: return VK_FORMAT_BC4_UNORM_BLOCK; - case texture_format::bc4_snorm: return VK_FORMAT_BC4_SNORM_BLOCK; - case texture_format::bc5_unorm: return VK_FORMAT_BC5_UNORM_BLOCK; - case texture_format::bc5_snorm: return VK_FORMAT_BC5_SNORM_BLOCK; - case texture_format::bc6h_ufloat: return VK_FORMAT_BC6H_UFLOAT_BLOCK; - case texture_format::bc6h_sfloat: return VK_FORMAT_BC6H_SFLOAT_BLOCK; - case texture_format::bc7_unorm: return VK_FORMAT_BC7_UNORM_BLOCK; - case texture_format::bc7_srgb: return VK_FORMAT_BC7_SRGB_BLOCK; + case texture_format::bc1_rgb_unorm: return vk::Format::eBc1RgbUnormBlock; + case texture_format::bc1_rgb_srgb: return vk::Format::eBc1RgbSrgbBlock; + case texture_format::bc1_rgba_unorm: return vk::Format::eBc1RgbaUnormBlock; + case texture_format::bc1_rgba_srgb: return vk::Format::eBc1RgbaSrgbBlock; + case texture_format::bc2_unorm: return vk::Format::eBc2UnormBlock; + case texture_format::bc2_srgb: return vk::Format::eBc2SrgbBlock; + case texture_format::bc3_unorm: return vk::Format::eBc3UnormBlock; + case texture_format::bc3_srgb: return vk::Format::eBc3SrgbBlock; + case texture_format::bc4_unorm: return vk::Format::eBc4UnormBlock; + case texture_format::bc4_snorm: return vk::Format::eBc4SnormBlock; + case texture_format::bc5_unorm: return vk::Format::eBc5UnormBlock; + case texture_format::bc5_snorm: return vk::Format::eBc5SnormBlock; + case texture_format::bc6h_ufloat: return vk::Format::eBc6HUfloatBlock; + case texture_format::bc6h_sfloat: return vk::Format::eBc6HSfloatBlock; + case texture_format::bc7_unorm: return vk::Format::eBc7UnormBlock; + case texture_format::bc7_srgb: return vk::Format::eBc7SrgbBlock; // 特殊格式 - case texture_format::r11g11b10_float: return VK_FORMAT_B10G11R11_UFLOAT_PACK32; - case texture_format::rgb9e5_float: return VK_FORMAT_E5B9G9R9_UFLOAT_PACK32; - case texture_format::rgb10a2_unorm: return VK_FORMAT_A2R10G10B10_UNORM_PACK32; - case texture_format::rgb10a2_uint: return VK_FORMAT_A2R10G10B10_UINT_PACK32; + case texture_format::r11g11b10_float: return vk::Format::eB10G11R11UfloatPack32; + case texture_format::rgb9e5_float: return vk::Format::eE5B9G9R9UfloatPack32; + case texture_format::rgb10a2_unorm: return vk::Format::eA2R10G10B10UnormPack32; + case texture_format::rgb10a2_uint: return vk::Format::eA2R10G10B10UintPack32; - default: return VK_FORMAT_UNDEFINED; + default: return vk::Format::eUndefined; } } /** - * @brief 从 VkFormat 转换为 texture_format + * @brief 从 vk::Format 转换为 texture_format * @param format Vulkan 格式 * @return 纹理格式 */ -[[nodiscard]] constexpr texture_format from_vulkan_format(VkFormat format) noexcept { +[[nodiscard]] constexpr texture_format from_vulkan_format(vk::Format format) noexcept { switch (format) { - case VK_FORMAT_UNDEFINED: return texture_format::undefined; + case vk::Format::eUndefined: return texture_format::undefined; - case VK_FORMAT_R8_UNORM: return texture_format::r8_unorm; - case VK_FORMAT_R8_SNORM: return texture_format::r8_snorm; - case VK_FORMAT_R8_UINT: return texture_format::r8_uint; - case VK_FORMAT_R8_SINT: return texture_format::r8_sint; + case vk::Format::eR8Unorm: return texture_format::r8_unorm; + case vk::Format::eR8Snorm: return texture_format::r8_snorm; + case vk::Format::eR8Uint: return texture_format::r8_uint; + case vk::Format::eR8Sint: return texture_format::r8_sint; - case VK_FORMAT_R8G8_UNORM: return texture_format::rg8_unorm; - case VK_FORMAT_R8G8_SNORM: return texture_format::rg8_snorm; - case VK_FORMAT_R8G8_UINT: return texture_format::rg8_uint; - case VK_FORMAT_R8G8_SINT: return texture_format::rg8_sint; + case vk::Format::eR8G8Unorm: return texture_format::rg8_unorm; + case vk::Format::eR8G8Snorm: return texture_format::rg8_snorm; + case vk::Format::eR8G8Uint: return texture_format::rg8_uint; + case vk::Format::eR8G8Sint: return texture_format::rg8_sint; - case VK_FORMAT_R8G8B8A8_UNORM: return texture_format::rgba8_unorm; - case VK_FORMAT_R8G8B8A8_SRGB: return texture_format::rgba8_srgb; - case VK_FORMAT_R8G8B8A8_SNORM: return texture_format::rgba8_snorm; - case VK_FORMAT_R8G8B8A8_UINT: return texture_format::rgba8_uint; - case VK_FORMAT_R8G8B8A8_SINT: return texture_format::rgba8_sint; + case vk::Format::eR8G8B8A8Unorm: return texture_format::rgba8_unorm; + case vk::Format::eR8G8B8A8Srgb: return texture_format::rgba8_srgb; + case vk::Format::eR8G8B8A8Snorm: return texture_format::rgba8_snorm; + case vk::Format::eR8G8B8A8Uint: return texture_format::rgba8_uint; + case vk::Format::eR8G8B8A8Sint: return texture_format::rgba8_sint; - case VK_FORMAT_B8G8R8A8_UNORM: return texture_format::bgra8_unorm; - case VK_FORMAT_B8G8R8A8_SRGB: return texture_format::bgra8_srgb; + case vk::Format::eB8G8R8A8Unorm: return texture_format::bgra8_unorm; + case vk::Format::eB8G8R8A8Srgb: return texture_format::bgra8_srgb; - case VK_FORMAT_R16_SFLOAT: return texture_format::r16_float; - case VK_FORMAT_R16_UNORM: return texture_format::r16_unorm; - case VK_FORMAT_R16_SNORM: return texture_format::r16_snorm; - case VK_FORMAT_R16_UINT: return texture_format::r16_uint; - case VK_FORMAT_R16_SINT: return texture_format::r16_sint; + case vk::Format::eR16Sfloat: return texture_format::r16_float; + case vk::Format::eR16Unorm: return texture_format::r16_unorm; + case vk::Format::eR16Snorm: return texture_format::r16_snorm; + case vk::Format::eR16Uint: return texture_format::r16_uint; + case vk::Format::eR16Sint: return texture_format::r16_sint; - case VK_FORMAT_R16G16_SFLOAT: return texture_format::rg16_float; - case VK_FORMAT_R16G16_UNORM: return texture_format::rg16_unorm; - case VK_FORMAT_R16G16_SNORM: return texture_format::rg16_snorm; - case VK_FORMAT_R16G16_UINT: return texture_format::rg16_uint; - case VK_FORMAT_R16G16_SINT: return texture_format::rg16_sint; + case vk::Format::eR16G16Sfloat: return texture_format::rg16_float; + case vk::Format::eR16G16Unorm: return texture_format::rg16_unorm; + case vk::Format::eR16G16Snorm: return texture_format::rg16_snorm; + case vk::Format::eR16G16Uint: return texture_format::rg16_uint; + case vk::Format::eR16G16Sint: return texture_format::rg16_sint; - case VK_FORMAT_R16G16B16A16_SFLOAT: return texture_format::rgba16_float; - case VK_FORMAT_R16G16B16A16_UNORM: return texture_format::rgba16_unorm; - case VK_FORMAT_R16G16B16A16_SNORM: return texture_format::rgba16_snorm; - case VK_FORMAT_R16G16B16A16_UINT: return texture_format::rgba16_uint; - case VK_FORMAT_R16G16B16A16_SINT: return texture_format::rgba16_sint; + case vk::Format::eR16G16B16A16Sfloat: return texture_format::rgba16_float; + case vk::Format::eR16G16B16A16Unorm: return texture_format::rgba16_unorm; + case vk::Format::eR16G16B16A16Snorm: return texture_format::rgba16_snorm; + case vk::Format::eR16G16B16A16Uint: return texture_format::rgba16_uint; + case vk::Format::eR16G16B16A16Sint: return texture_format::rgba16_sint; - case VK_FORMAT_R32_SFLOAT: return texture_format::r32_float; - case VK_FORMAT_R32_UINT: return texture_format::r32_uint; - case VK_FORMAT_R32_SINT: return texture_format::r32_sint; + case vk::Format::eR32Sfloat: return texture_format::r32_float; + case vk::Format::eR32Uint: return texture_format::r32_uint; + case vk::Format::eR32Sint: return texture_format::r32_sint; - case VK_FORMAT_R32G32_SFLOAT: return texture_format::rg32_float; - case VK_FORMAT_R32G32_UINT: return texture_format::rg32_uint; - case VK_FORMAT_R32G32_SINT: return texture_format::rg32_sint; + case vk::Format::eR32G32Sfloat: return texture_format::rg32_float; + case vk::Format::eR32G32Uint: return texture_format::rg32_uint; + case vk::Format::eR32G32Sint: return texture_format::rg32_sint; - case VK_FORMAT_R32G32B32_SFLOAT: return texture_format::rgb32_float; - case VK_FORMAT_R32G32B32_UINT: return texture_format::rgb32_uint; - case VK_FORMAT_R32G32B32_SINT: return texture_format::rgb32_sint; + case vk::Format::eR32G32B32Sfloat: return texture_format::rgb32_float; + case vk::Format::eR32G32B32Uint: return texture_format::rgb32_uint; + case vk::Format::eR32G32B32Sint: return texture_format::rgb32_sint; - case VK_FORMAT_R32G32B32A32_SFLOAT: return texture_format::rgba32_float; - case VK_FORMAT_R32G32B32A32_UINT: return texture_format::rgba32_uint; - case VK_FORMAT_R32G32B32A32_SINT: return texture_format::rgba32_sint; + case vk::Format::eR32G32B32A32Sfloat: return texture_format::rgba32_float; + case vk::Format::eR32G32B32A32Uint: return texture_format::rgba32_uint; + case vk::Format::eR32G32B32A32Sint: return texture_format::rgba32_sint; - case VK_FORMAT_D16_UNORM: return texture_format::depth16_unorm; - case VK_FORMAT_X8_D24_UNORM_PACK32: return texture_format::depth24_unorm; - case VK_FORMAT_D32_SFLOAT: return texture_format::depth32_float; - case VK_FORMAT_D24_UNORM_S8_UINT: return texture_format::depth24_unorm_stencil8_uint; - case VK_FORMAT_D32_SFLOAT_S8_UINT: return texture_format::depth32_float_stencil8_uint; - case VK_FORMAT_S8_UINT: return texture_format::stencil8_uint; + case vk::Format::eD16Unorm: return texture_format::depth16_unorm; + case vk::Format::eX8D24UnormPack32: return texture_format::depth24_unorm; + case vk::Format::eD32Sfloat: return texture_format::depth32_float; + case vk::Format::eD24UnormS8Uint: return texture_format::depth24_unorm_stencil8_uint; + case vk::Format::eD32SfloatS8Uint: return texture_format::depth32_float_stencil8_uint; + case vk::Format::eS8Uint: return texture_format::stencil8_uint; - case VK_FORMAT_BC1_RGB_UNORM_BLOCK: return texture_format::bc1_rgb_unorm; - case VK_FORMAT_BC1_RGB_SRGB_BLOCK: return texture_format::bc1_rgb_srgb; - case VK_FORMAT_BC1_RGBA_UNORM_BLOCK: return texture_format::bc1_rgba_unorm; - case VK_FORMAT_BC1_RGBA_SRGB_BLOCK: return texture_format::bc1_rgba_srgb; - case VK_FORMAT_BC2_UNORM_BLOCK: return texture_format::bc2_unorm; - case VK_FORMAT_BC2_SRGB_BLOCK: return texture_format::bc2_srgb; - case VK_FORMAT_BC3_UNORM_BLOCK: return texture_format::bc3_unorm; - case VK_FORMAT_BC3_SRGB_BLOCK: return texture_format::bc3_srgb; - case VK_FORMAT_BC4_UNORM_BLOCK: return texture_format::bc4_unorm; - case VK_FORMAT_BC4_SNORM_BLOCK: return texture_format::bc4_snorm; - case VK_FORMAT_BC5_UNORM_BLOCK: return texture_format::bc5_unorm; - case VK_FORMAT_BC5_SNORM_BLOCK: return texture_format::bc5_snorm; - case VK_FORMAT_BC6H_UFLOAT_BLOCK: return texture_format::bc6h_ufloat; - case VK_FORMAT_BC6H_SFLOAT_BLOCK: return texture_format::bc6h_sfloat; - case VK_FORMAT_BC7_UNORM_BLOCK: return texture_format::bc7_unorm; - case VK_FORMAT_BC7_SRGB_BLOCK: return texture_format::bc7_srgb; + case vk::Format::eBc1RgbUnormBlock: return texture_format::bc1_rgb_unorm; + case vk::Format::eBc1RgbSrgbBlock: return texture_format::bc1_rgb_srgb; + case vk::Format::eBc1RgbaUnormBlock: return texture_format::bc1_rgba_unorm; + case vk::Format::eBc1RgbaSrgbBlock: return texture_format::bc1_rgba_srgb; + case vk::Format::eBc2UnormBlock: return texture_format::bc2_unorm; + case vk::Format::eBc2SrgbBlock: return texture_format::bc2_srgb; + case vk::Format::eBc3UnormBlock: return texture_format::bc3_unorm; + case vk::Format::eBc3SrgbBlock: return texture_format::bc3_srgb; + case vk::Format::eBc4UnormBlock: return texture_format::bc4_unorm; + case vk::Format::eBc4SnormBlock: return texture_format::bc4_snorm; + case vk::Format::eBc5UnormBlock: return texture_format::bc5_unorm; + case vk::Format::eBc5SnormBlock: return texture_format::bc5_snorm; + case vk::Format::eBc6HUfloatBlock: return texture_format::bc6h_ufloat; + case vk::Format::eBc6HSfloatBlock: return texture_format::bc6h_sfloat; + case vk::Format::eBc7UnormBlock: return texture_format::bc7_unorm; + case vk::Format::eBc7SrgbBlock: return texture_format::bc7_srgb; - case VK_FORMAT_B10G11R11_UFLOAT_PACK32: return texture_format::r11g11b10_float; - case VK_FORMAT_E5B9G9R9_UFLOAT_PACK32: return texture_format::rgb9e5_float; - case VK_FORMAT_A2R10G10B10_UNORM_PACK32: return texture_format::rgb10a2_unorm; - case VK_FORMAT_A2R10G10B10_UINT_PACK32: return texture_format::rgb10a2_uint; + case vk::Format::eB10G11R11UfloatPack32: return texture_format::r11g11b10_float; + case vk::Format::eE5B9G9R9UfloatPack32: return texture_format::rgb9e5_float; + case vk::Format::eA2R10G10B10UnormPack32: return texture_format::rgb10a2_unorm; + case vk::Format::eA2R10G10B10UintPack32: return texture_format::rgb10a2_uint; default: return texture_format::undefined; } @@ -839,50 +799,50 @@ enum class texture_type : u32 { }; /** - * @brief 将 texture_type 转换为 VkImageType + * @brief 将 texture_type 转换为 vk::ImageType * @param type 纹理类型 * @return Vulkan 图像类型 */ -[[nodiscard]] constexpr VkImageType to_vulkan_image_type(texture_type type) noexcept { +[[nodiscard]] constexpr vk::ImageType to_vulkan_image_type(texture_type type) noexcept { switch (type) { case texture_type::texture_1d: case texture_type::texture_1d_array: - return VK_IMAGE_TYPE_1D; + return vk::ImageType::e1D; case texture_type::texture_2d: case texture_type::texture_2d_array: case texture_type::texture_cube: case texture_type::texture_cube_array: - return VK_IMAGE_TYPE_2D; + return vk::ImageType::e2D; case texture_type::texture_3d: - return VK_IMAGE_TYPE_3D; + return vk::ImageType::e3D; default: - return VK_IMAGE_TYPE_2D; + return vk::ImageType::e2D; } } /** - * @brief 将 texture_type 转换为 VkImageViewType + * @brief 将 texture_type 转换为 vk::ImageViewType * @param type 纹理类型 * @return Vulkan 图像视图类型 */ -[[nodiscard]] constexpr VkImageViewType to_vulkan_image_view_type(texture_type type) noexcept { +[[nodiscard]] constexpr vk::ImageViewType to_vulkan_image_view_type(texture_type type) noexcept { switch (type) { case texture_type::texture_1d: - return VK_IMAGE_VIEW_TYPE_1D; + return vk::ImageViewType::e1D; case texture_type::texture_2d: - return VK_IMAGE_VIEW_TYPE_2D; + return vk::ImageViewType::e2D; case texture_type::texture_3d: - return VK_IMAGE_VIEW_TYPE_3D; + return vk::ImageViewType::e3D; case texture_type::texture_cube: - return VK_IMAGE_VIEW_TYPE_CUBE; + return vk::ImageViewType::eCube; case texture_type::texture_1d_array: - return VK_IMAGE_VIEW_TYPE_1D_ARRAY; + return vk::ImageViewType::e1DArray; case texture_type::texture_2d_array: - return VK_IMAGE_VIEW_TYPE_2D_ARRAY; + return vk::ImageViewType::e2DArray; case texture_type::texture_cube_array: - return VK_IMAGE_VIEW_TYPE_CUBE_ARRAY; + return vk::ImageViewType::eCubeArray; default: - return VK_IMAGE_VIEW_TYPE_2D; + return vk::ImageViewType::e2D; } } @@ -913,79 +873,39 @@ enum class texture_usage : u32 { /// 瞬态附件 transient_attachment = 1 << 7, }; +MILAI_ENABLE_FLAG_ENUM(texture_usage); /** - * @brief 按位或运算符 - * @param lhs 左操作数 - * @param rhs 右操作数 - * @return 组合后的 texture_usage - */ -[[nodiscard]] constexpr texture_usage operator|(texture_usage lhs, texture_usage rhs) noexcept { - return static_cast(static_cast(lhs) | static_cast(rhs)); -} - -/** - * @brief 按位与运算符 - * @param lhs 左操作数 - * @param rhs 右操作数 - * @return 组合后的 texture_usage - */ -[[nodiscard]] constexpr texture_usage operator&(texture_usage lhs, texture_usage rhs) noexcept { - return static_cast(static_cast(lhs) & static_cast(rhs)); -} - -/** - * @brief 按位或赋值运算符 - * @param lhs 左操作数 - * @param rhs 右操作数 - * @return 组合后的 texture_usage 引用 - */ -constexpr texture_usage& operator|=(texture_usage& lhs, texture_usage rhs) noexcept { - lhs = lhs | rhs; - return lhs; -} - -/** - * @brief 检查 texture_usage 是否包含指定标志 - * @param usage 要检查的用途 - * @param flag 要检查的标志 - * @return 如果包含返回 true - */ -[[nodiscard]] constexpr bool has_flag(texture_usage usage, texture_usage flag) noexcept { - return (static_cast(usage) & static_cast(flag)) != 0; -} - -/** - * @brief 将 texture_usage 转换为 VkImageUsageFlags + * @brief 将 texture_usage 转换为 vk::ImageUsageFlags * @param usage 纹理用途 * @return Vulkan 图像用途标志 */ -[[nodiscard]] constexpr VkImageUsageFlags to_vulkan_image_usage(texture_usage usage) noexcept { - VkImageUsageFlags flags = 0; +[[nodiscard]] constexpr vk::ImageUsageFlags to_vulkan_image_usage(texture_usage usage) noexcept { + vk::ImageUsageFlags flags{}; if (has_flag(usage, texture_usage::sampled)) { - flags |= VK_IMAGE_USAGE_SAMPLED_BIT; + flags |= vk::ImageUsageFlagBits::eSampled; } if (has_flag(usage, texture_usage::storage)) { - flags |= VK_IMAGE_USAGE_STORAGE_BIT; + flags |= vk::ImageUsageFlagBits::eStorage; } if (has_flag(usage, texture_usage::color_attachment)) { - flags |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; + flags |= vk::ImageUsageFlagBits::eColorAttachment; } if (has_flag(usage, texture_usage::depth_stencil_attachment)) { - flags |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; + flags |= vk::ImageUsageFlagBits::eDepthStencilAttachment; } if (has_flag(usage, texture_usage::input_attachment)) { - flags |= VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT; + flags |= vk::ImageUsageFlagBits::eInputAttachment; } if (has_flag(usage, texture_usage::transfer_src)) { - flags |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT; + flags |= vk::ImageUsageFlagBits::eTransferSrc; } if (has_flag(usage, texture_usage::transfer_dst)) { - flags |= VK_IMAGE_USAGE_TRANSFER_DST_BIT; + flags |= vk::ImageUsageFlagBits::eTransferDst; } if (has_flag(usage, texture_usage::transient_attachment)) { - flags |= VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT; + flags |= vk::ImageUsageFlagBits::eTransientAttachment; } return flags; @@ -1006,15 +926,15 @@ enum class sampler_filter : u32 { }; /** - * @brief 将 sampler_filter 转换为 VkFilter + * @brief 将 sampler_filter 转换为 vk::Filter * @param filter 过滤模式 * @return Vulkan 过滤模式 */ -[[nodiscard]] constexpr VkFilter to_vulkan_filter(sampler_filter filter) noexcept { +[[nodiscard]] constexpr vk::Filter to_vulkan_filter(sampler_filter filter) noexcept { switch (filter) { - case sampler_filter::nearest: return VK_FILTER_NEAREST; - case sampler_filter::linear: return VK_FILTER_LINEAR; - default: return VK_FILTER_LINEAR; + case sampler_filter::nearest: return vk::Filter::eNearest; + case sampler_filter::linear: return vk::Filter::eLinear; + default: return vk::Filter::eLinear; } } @@ -1035,18 +955,18 @@ enum class sampler_address_mode : u32 { }; /** - * @brief 将 sampler_address_mode 转换为 VkSamplerAddressMode + * @brief 将 sampler_address_mode 转换为 vk::SamplerAddressMode * @param mode 寻址模式 * @return Vulkan 寻址模式 */ -[[nodiscard]] constexpr VkSamplerAddressMode to_vulkan_address_mode(sampler_address_mode mode) noexcept { +[[nodiscard]] constexpr vk::SamplerAddressMode to_vulkan_address_mode(sampler_address_mode mode) noexcept { switch (mode) { - case sampler_address_mode::repeat: return VK_SAMPLER_ADDRESS_MODE_REPEAT; - case sampler_address_mode::mirrored_repeat: return VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT; - case sampler_address_mode::clamp_to_edge: return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; - case sampler_address_mode::clamp_to_border: return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER; - case sampler_address_mode::mirror_clamp_to_edge: return VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE; - default: return VK_SAMPLER_ADDRESS_MODE_REPEAT; + case sampler_address_mode::repeat: return vk::SamplerAddressMode::eRepeat; + case sampler_address_mode::mirrored_repeat: return vk::SamplerAddressMode::eMirroredRepeat; + case sampler_address_mode::clamp_to_edge: return vk::SamplerAddressMode::eClampToEdge; + case sampler_address_mode::clamp_to_border: return vk::SamplerAddressMode::eClampToBorder; + case sampler_address_mode::mirror_clamp_to_edge: return vk::SamplerAddressMode::eMirrorClampToEdge; + default: return vk::SamplerAddressMode::eRepeat; } } @@ -1061,15 +981,15 @@ enum class sampler_mipmap_mode : u32 { }; /** - * @brief 将 sampler_mipmap_mode 转换为 VkSamplerMipmapMode + * @brief 将 sampler_mipmap_mode 转换为 vk::SamplerMipmapMode * @param mode mipmap 模式 * @return Vulkan mipmap 模式 */ -[[nodiscard]] constexpr VkSamplerMipmapMode to_vulkan_mipmap_mode(sampler_mipmap_mode mode) noexcept { +[[nodiscard]] constexpr vk::SamplerMipmapMode to_vulkan_mipmap_mode(sampler_mipmap_mode mode) noexcept { switch (mode) { - case sampler_mipmap_mode::nearest: return VK_SAMPLER_MIPMAP_MODE_NEAREST; - case sampler_mipmap_mode::linear: return VK_SAMPLER_MIPMAP_MODE_LINEAR; - default: return VK_SAMPLER_MIPMAP_MODE_LINEAR; + case sampler_mipmap_mode::nearest: return vk::SamplerMipmapMode::eNearest; + case sampler_mipmap_mode::linear: return vk::SamplerMipmapMode::eLinear; + default: return vk::SamplerMipmapMode::eLinear; } } @@ -1116,19 +1036,19 @@ enum class border_color : u32 { }; /** - * @brief 将 border_color 转换为 VkBorderColor + * @brief 将 border_color 转换为 vk::BorderColor * @param color 边界颜色 * @return Vulkan 边界颜色 */ -[[nodiscard]] constexpr VkBorderColor to_vulkan_border_color(border_color color) noexcept { +[[nodiscard]] constexpr vk::BorderColor to_vulkan_border_color(border_color color) noexcept { switch (color) { - case border_color::transparent_black_float: return VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK; - case border_color::transparent_black_int: return VK_BORDER_COLOR_INT_TRANSPARENT_BLACK; - case border_color::opaque_black_float: return VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK; - case border_color::opaque_black_int: return VK_BORDER_COLOR_INT_OPAQUE_BLACK; - case border_color::opaque_white_float: return VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE; - case border_color::opaque_white_int: return VK_BORDER_COLOR_INT_OPAQUE_WHITE; - default: return VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK; + case border_color::transparent_black_float: return vk::BorderColor::eFloatTransparentBlack; + case border_color::transparent_black_int: return vk::BorderColor::eIntTransparentBlack; + case border_color::opaque_black_float: return vk::BorderColor::eFloatOpaqueBlack; + case border_color::opaque_black_int: return vk::BorderColor::eIntOpaqueBlack; + case border_color::opaque_white_float: return vk::BorderColor::eFloatOpaqueWhite; + case border_color::opaque_white_int: return vk::BorderColor::eIntOpaqueWhite; + default: return vk::BorderColor::eFloatTransparentBlack; } } @@ -1155,21 +1075,21 @@ enum class compare_op : u32 { }; /** - * @brief 将 compare_op 转换为 VkCompareOp + * @brief 将 compare_op 转换为 vk::CompareOp * @param op 比较操作 * @return Vulkan 比较操作 */ -[[nodiscard]] constexpr VkCompareOp to_vulkan_compare_op(compare_op op) noexcept { +[[nodiscard]] constexpr vk::CompareOp to_vulkan_compare_op(compare_op op) noexcept { switch (op) { - case compare_op::never: return VK_COMPARE_OP_NEVER; - case compare_op::less: return VK_COMPARE_OP_LESS; - case compare_op::equal: return VK_COMPARE_OP_EQUAL; - case compare_op::less_or_equal: return VK_COMPARE_OP_LESS_OR_EQUAL; - case compare_op::greater: return VK_COMPARE_OP_GREATER; - case compare_op::not_equal: return VK_COMPARE_OP_NOT_EQUAL; - case compare_op::greater_or_equal: return VK_COMPARE_OP_GREATER_OR_EQUAL; - case compare_op::always: return VK_COMPARE_OP_ALWAYS; - default: return VK_COMPARE_OP_ALWAYS; + case compare_op::never: return vk::CompareOp::eNever; + case compare_op::less: return vk::CompareOp::eLess; + case compare_op::equal: return vk::CompareOp::eEqual; + case compare_op::less_or_equal: return vk::CompareOp::eLessOrEqual; + case compare_op::greater: return vk::CompareOp::eGreater; + case compare_op::not_equal: return vk::CompareOp::eNotEqual; + case compare_op::greater_or_equal: return vk::CompareOp::eGreaterOrEqual; + case compare_op::always: return vk::CompareOp::eAlways; + default: return vk::CompareOp::eAlways; } } @@ -1190,56 +1110,27 @@ enum class image_aspect : u32 { /// 元数据 metadata = 1 << 3, }; +MILAI_ENABLE_FLAG_ENUM(image_aspect); /** - * @brief 按位或运算符 - * @param lhs 左操作数 - * @param rhs 右操作数 - * @return 组合后的 image_aspect - */ -[[nodiscard]] constexpr image_aspect operator|(image_aspect lhs, image_aspect rhs) noexcept { - return static_cast(static_cast(lhs) | static_cast(rhs)); -} - -/** - * @brief 按位与运算符 - * @param lhs 左操作数 - * @param rhs 右操作数 - * @return 组合后的 image_aspect - */ -[[nodiscard]] constexpr image_aspect operator&(image_aspect lhs, image_aspect rhs) noexcept { - return static_cast(static_cast(lhs) & static_cast(rhs)); -} - -/** - * @brief 检查 image_aspect 是否包含指定标志 - * @param aspect 要检查的 aspect - * @param flag 要检查的标志 - * @return 如果包含返回 true - */ -[[nodiscard]] constexpr bool has_flag(image_aspect aspect, image_aspect flag) noexcept { - return (static_cast(aspect) & static_cast(flag)) != 0; -} - -/** - * @brief 将 image_aspect 转换为 VkImageAspectFlags + * @brief 将 image_aspect 转换为 vk::ImageAspectFlags * @param aspect 图像 aspect * @return Vulkan 图像 aspect 标志 */ -[[nodiscard]] constexpr VkImageAspectFlags to_vulkan_image_aspect(image_aspect aspect) noexcept { - VkImageAspectFlags flags = 0; +[[nodiscard]] constexpr vk::ImageAspectFlags to_vulkan_image_aspect(image_aspect aspect) noexcept { + vk::ImageAspectFlags flags{}; if (has_flag(aspect, image_aspect::color)) { - flags |= VK_IMAGE_ASPECT_COLOR_BIT; + flags |= vk::ImageAspectFlagBits::eColor; } if (has_flag(aspect, image_aspect::depth)) { - flags |= VK_IMAGE_ASPECT_DEPTH_BIT; + flags |= vk::ImageAspectFlagBits::eDepth; } if (has_flag(aspect, image_aspect::stencil)) { - flags |= VK_IMAGE_ASPECT_STENCIL_BIT; + flags |= vk::ImageAspectFlagBits::eStencil; } if (has_flag(aspect, image_aspect::metadata)) { - flags |= VK_IMAGE_ASPECT_METADATA_BIT; + flags |= vk::ImageAspectFlagBits::eMetadata; } return flags; @@ -1310,31 +1201,31 @@ enum class image_layout : u32 { }; /** - * @brief 将 image_layout 转换为 VkImageLayout + * @brief 将 image_layout 转换为 vk::ImageLayout * @param layout 图像布局 * @return Vulkan 图像布局 */ -[[nodiscard]] constexpr VkImageLayout to_vulkan_image_layout(image_layout layout) noexcept { +[[nodiscard]] constexpr vk::ImageLayout to_vulkan_image_layout(image_layout layout) noexcept { switch (layout) { - case image_layout::undefined: return VK_IMAGE_LAYOUT_UNDEFINED; - case image_layout::general: return VK_IMAGE_LAYOUT_GENERAL; - case image_layout::color_attachment_optimal: return VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - case image_layout::depth_stencil_attachment_optimal: return VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; - case image_layout::depth_stencil_read_only_optimal: return VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL; - case image_layout::shader_read_only_optimal: return VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; - case image_layout::transfer_src_optimal: return VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; - case image_layout::transfer_dst_optimal: return VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; - case image_layout::preinitialized: return VK_IMAGE_LAYOUT_PREINITIALIZED; - case image_layout::depth_read_only_stencil_attachment_optimal: return VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL; - case image_layout::depth_attachment_stencil_read_only_optimal: return VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL; - case image_layout::depth_attachment_optimal: return VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL; - case image_layout::depth_read_only_optimal: return VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL; - case image_layout::stencil_attachment_optimal: return VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL; - case image_layout::stencil_read_only_optimal: return VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL; - case image_layout::read_only_optimal: return VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL; - case image_layout::attachment_optimal: return VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL; - case image_layout::present_src: return VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; - default: return VK_IMAGE_LAYOUT_UNDEFINED; + case image_layout::undefined: return vk::ImageLayout::eUndefined; + case image_layout::general: return vk::ImageLayout::eGeneral; + case image_layout::color_attachment_optimal: return vk::ImageLayout::eColorAttachmentOptimal; + case image_layout::depth_stencil_attachment_optimal: return vk::ImageLayout::eDepthStencilAttachmentOptimal; + case image_layout::depth_stencil_read_only_optimal: return vk::ImageLayout::eDepthStencilReadOnlyOptimal; + case image_layout::shader_read_only_optimal: return vk::ImageLayout::eShaderReadOnlyOptimal; + case image_layout::transfer_src_optimal: return vk::ImageLayout::eTransferSrcOptimal; + case image_layout::transfer_dst_optimal: return vk::ImageLayout::eTransferDstOptimal; + case image_layout::preinitialized: return vk::ImageLayout::ePreinitialized; + case image_layout::depth_read_only_stencil_attachment_optimal: return vk::ImageLayout::eDepthReadOnlyStencilAttachmentOptimal; + case image_layout::depth_attachment_stencil_read_only_optimal: return vk::ImageLayout::eDepthAttachmentStencilReadOnlyOptimal; + case image_layout::depth_attachment_optimal: return vk::ImageLayout::eDepthAttachmentOptimal; + case image_layout::depth_read_only_optimal: return vk::ImageLayout::eDepthReadOnlyOptimal; + case image_layout::stencil_attachment_optimal: return vk::ImageLayout::eStencilAttachmentOptimal; + case image_layout::stencil_read_only_optimal: return vk::ImageLayout::eStencilReadOnlyOptimal; + case image_layout::read_only_optimal: return vk::ImageLayout::eReadOnlyOptimal; + case image_layout::attachment_optimal: return vk::ImageLayout::eAttachmentOptimal; + case image_layout::present_src: return vk::ImageLayout::ePresentSrcKHR; + default: return vk::ImageLayout::eUndefined; } } @@ -1363,20 +1254,20 @@ enum class sample_count : u32 { }; /** - * @brief 将 sample_count 转换为 VkSampleCountFlagBits + * @brief 将 sample_count 转换为 vk::SampleCountFlagBits * @param count 采样数 * @return Vulkan 采样数标志 */ -[[nodiscard]] constexpr VkSampleCountFlagBits to_vulkan_sample_count(sample_count count) noexcept { +[[nodiscard]] constexpr vk::SampleCountFlagBits to_vulkan_sample_count(sample_count count) noexcept { switch (count) { - case sample_count::count_1: return VK_SAMPLE_COUNT_1_BIT; - case sample_count::count_2: return VK_SAMPLE_COUNT_2_BIT; - case sample_count::count_4: return VK_SAMPLE_COUNT_4_BIT; - case sample_count::count_8: return VK_SAMPLE_COUNT_8_BIT; - case sample_count::count_16: return VK_SAMPLE_COUNT_16_BIT; - case sample_count::count_32: return VK_SAMPLE_COUNT_32_BIT; - case sample_count::count_64: return VK_SAMPLE_COUNT_64_BIT; - default: return VK_SAMPLE_COUNT_1_BIT; + case sample_count::count_1: return vk::SampleCountFlagBits::e1; + case sample_count::count_2: return vk::SampleCountFlagBits::e2; + case sample_count::count_4: return vk::SampleCountFlagBits::e4; + case sample_count::count_8: return vk::SampleCountFlagBits::e8; + case sample_count::count_16: return vk::SampleCountFlagBits::e16; + case sample_count::count_32: return vk::SampleCountFlagBits::e32; + case sample_count::count_64: return vk::SampleCountFlagBits::e64; + default: return vk::SampleCountFlagBits::e1; } } @@ -1415,25 +1306,25 @@ enum class descriptor_type : u32 { }; /** - * @brief 将 descriptor_type 转换为 VkDescriptorType + * @brief 将 descriptor_type 转换为 vk::DescriptorType * @param type 描述符类型 * @return Vulkan 描述符类型 */ -[[nodiscard]] constexpr VkDescriptorType to_vulkan_descriptor_type(descriptor_type type) noexcept { +[[nodiscard]] constexpr vk::DescriptorType to_vulkan_descriptor_type(descriptor_type type) noexcept { switch (type) { - case descriptor_type::sampler: return VK_DESCRIPTOR_TYPE_SAMPLER; - case descriptor_type::combined_image_sampler: return VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; - case descriptor_type::sampled_image: return VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; - case descriptor_type::storage_image: return VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; - case descriptor_type::uniform_texel_buffer: return VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER; - case descriptor_type::storage_texel_buffer: return VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER; - case descriptor_type::uniform_buffer: return VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; - case descriptor_type::storage_buffer: return VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; - case descriptor_type::uniform_buffer_dynamic: return VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC; - case descriptor_type::storage_buffer_dynamic: return VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC; - case descriptor_type::input_attachment: return VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT; - case descriptor_type::acceleration_structure: return VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR; - default: return VK_DESCRIPTOR_TYPE_SAMPLER; + case descriptor_type::sampler: return vk::DescriptorType::eSampler; + case descriptor_type::combined_image_sampler: return vk::DescriptorType::eCombinedImageSampler; + case descriptor_type::sampled_image: return vk::DescriptorType::eSampledImage; + case descriptor_type::storage_image: return vk::DescriptorType::eStorageImage; + case descriptor_type::uniform_texel_buffer: return vk::DescriptorType::eUniformTexelBuffer; + case descriptor_type::storage_texel_buffer: return vk::DescriptorType::eStorageTexelBuffer; + case descriptor_type::uniform_buffer: return vk::DescriptorType::eUniformBuffer; + case descriptor_type::storage_buffer: return vk::DescriptorType::eStorageBuffer; + case descriptor_type::uniform_buffer_dynamic: return vk::DescriptorType::eUniformBufferDynamic; + case descriptor_type::storage_buffer_dynamic: return vk::DescriptorType::eStorageBufferDynamic; + case descriptor_type::input_attachment: return vk::DescriptorType::eInputAttachment; + case descriptor_type::acceleration_structure: return vk::DescriptorType::eAccelerationStructureKHR; + default: return vk::DescriptorType::eSampler; } } diff --git a/src/resource/sampler.cpp b/src/resource/sampler.cpp index 3b5580d..73bd985 100644 --- a/src/resource/sampler.cpp +++ b/src/resource/sampler.cpp @@ -7,6 +7,7 @@ #include "sampler.hpp" #include "logger.hpp" +#include "vulkan_types.hpp" namespace milai { @@ -14,25 +15,25 @@ namespace milai { // Sampler 类实现 // ================================================================================================ -sampler::sampler(VkDevice device, const sampler_info& info) +sampler::sampler(vk::Device device, const sampler_info& info) : device_(device) , info_(info) { - if (device_ == VK_NULL_HANDLE) { - log_error("Sampler created with null device"); + if (!device_) { + MILAI_LOG_ERROR("Sampler created with null device"); return; } auto result = create_sampler(); if (!result.has_value()) { - log_error("Failed to create sampler: {}", result.error().message); + MILAI_LOG_ERROR("Failed to create sampler: {}", result.error().message); } } sampler::~sampler() { - if (sampler_ != VK_NULL_HANDLE && device_ != VK_NULL_HANDLE) { - vkDestroySampler(device_, sampler_, nullptr); - sampler_ = VK_NULL_HANDLE; + if (sampler_ && device_) { + device_.destroySampler(sampler_); + sampler_ = vk::Sampler{}; } } @@ -41,14 +42,14 @@ sampler::sampler(sampler&& other) noexcept , sampler_(other.sampler_) , info_(std::move(other.info_)) { - other.sampler_ = VK_NULL_HANDLE; + other.sampler_ = vk::Sampler{}; } sampler& sampler::operator=(sampler&& other) noexcept { if (this != &other) { // 释放当前资源 - if (sampler_ != VK_NULL_HANDLE && device_ != VK_NULL_HANDLE) { - vkDestroySampler(device_, sampler_, nullptr); + if (sampler_ && device_) { + device_.destroySampler(sampler_); } // 移动资源 @@ -57,7 +58,7 @@ sampler& sampler::operator=(sampler&& other) noexcept { info_ = std::move(other.info_); // 清空源对象 - other.sampler_ = VK_NULL_HANDLE; + other.sampler_ = vk::Sampler{}; } return *this; } @@ -67,8 +68,7 @@ sampler& sampler::operator=(sampler&& other) noexcept { // ================================================================================================ void_result sampler::create_sampler() { - VkSamplerCreateInfo create_info{}; - create_info.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; + vk::SamplerCreateInfo create_info{}; create_info.magFilter = to_vulkan_filter(info_.mag_filter); create_info.minFilter = to_vulkan_filter(info_.min_filter); create_info.mipmapMode = to_vulkan_mipmap_mode(info_.mipmap_mode); @@ -76,20 +76,21 @@ void_result sampler::create_sampler() { create_info.addressModeV = to_vulkan_address_mode(info_.address_mode_v); create_info.addressModeW = to_vulkan_address_mode(info_.address_mode_w); create_info.mipLodBias = info_.mip_lod_bias; - create_info.anisotropyEnable = info_.anisotropy_enable ? VK_TRUE : VK_FALSE; + create_info.anisotropyEnable = info_.anisotropy_enable ? vk::True : vk::False; create_info.maxAnisotropy = info_.max_anisotropy; - create_info.compareEnable = info_.compare_enable ? VK_TRUE : VK_FALSE; + create_info.compareEnable = info_.compare_enable ? vk::True : vk::False; create_info.compareOp = to_vulkan_compare_op(info_.compare_op_); create_info.minLod = info_.min_lod; create_info.maxLod = info_.max_lod; create_info.borderColor = to_vulkan_border_color(info_.border_color_); - create_info.unnormalizedCoordinates = info_.unnormalized_coordinates ? VK_TRUE : VK_FALSE; + create_info.unnormalizedCoordinates = info_.unnormalized_coordinates ? vk::True : vk::False; - VkResult result = vkCreateSampler(device_, &create_info, nullptr, &sampler_); - if (result != VK_SUCCESS) { + auto [result, samp] = device_.createSampler(create_info); + if (result != vk::Result::eSuccess) { return make_void_error(error_code::vulkan_init_failed, - "Failed to create sampler: " + std::to_string(result)); + "Failed to create sampler: " + vk::to_string(result)); } + sampler_ = samp; return make_success(); } @@ -98,11 +99,11 @@ void_result sampler::create_sampler() { // 描述符信息 // ================================================================================================ -VkDescriptorImageInfo sampler::get_descriptor_info( - VkImageView view, - VkImageLayout layout) const noexcept { +vk::DescriptorImageInfo sampler::get_descriptor_info( + vk::ImageView view, + vk::ImageLayout layout) const noexcept { - VkDescriptorImageInfo info{}; + vk::DescriptorImageInfo info{}; info.sampler = sampler_; info.imageView = view; info.imageLayout = layout; @@ -115,13 +116,13 @@ VkDescriptorImageInfo sampler::get_descriptor_info( void sampler::on_created() { if (!info_.debug_name.empty()) { - log_debug("Sampler '{}' created", info_.debug_name); + MILAI_LOG_DEBUG("Sampler '{}' created", info_.debug_name); } } void sampler::on_destroying() { if (!info_.debug_name.empty()) { - log_debug("Sampler '{}' destroying", info_.debug_name); + MILAI_LOG_DEBUG("Sampler '{}' destroying", info_.debug_name); } } @@ -129,11 +130,11 @@ void sampler::on_destroying() { // Sampler Cache 实现 // ================================================================================================ -sampler_cache::sampler_cache(VkDevice device) +sampler_cache::sampler_cache(vk::Device device) : device_(device) { - if (device_ == VK_NULL_HANDLE) { - log_error("Sampler cache created with null device"); + if (!device_) { + MILAI_LOG_ERROR("Sampler cache created with null device"); } } @@ -157,7 +158,7 @@ std::shared_ptr sampler_cache::get_or_create(const sampler_info& info) // 创建新采样器 auto new_sampler = make_obj(device_, info); if (!new_sampler->is_valid()) { - log_error("Failed to create sampler for cache"); + MILAI_LOG_ERROR("Failed to create sampler for cache"); return nullptr; } @@ -183,11 +184,11 @@ void sampler_cache::clear() { } void sampler_cache::on_created() { - log_debug("Sampler cache created"); + MILAI_LOG_DEBUG("Sampler cache created"); } void sampler_cache::on_destroying() { - log_debug("Sampler cache destroying with {} cached samplers", cache_.size()); + MILAI_LOG_DEBUG("Sampler cache destroying with {} cached samplers", cache_.size()); } } // namespace milai \ No newline at end of file diff --git a/src/resource/sampler.hpp b/src/resource/sampler.hpp index c1727da..4ca3d11 100644 --- a/src/resource/sampler.hpp +++ b/src/resource/sampler.hpp @@ -14,8 +14,8 @@ #include "resource_types.hpp" #include "object.hpp" +#include "vulkan_types.hpp" -#include #include #include #include @@ -251,7 +251,7 @@ public: * @param device Vulkan 设备 * @param info 采样器创建信息 */ - sampler(VkDevice device, const sampler_info& info); + sampler(vk::Device device, const sampler_info& info); /** * @brief 析构函数 @@ -283,7 +283,7 @@ public: * @return 如果有效返回 true */ [[nodiscard]] bool is_valid() const noexcept { - return sampler_ != VK_NULL_HANDLE; + return sampler_; } // ============================================================================================ @@ -292,21 +292,21 @@ public: /** * @brief 获取 Vulkan Sampler 句柄 - * @return VkSampler 句柄 + * @return vk::Sampler 句柄 */ - [[nodiscard]] VkSampler get_vulkan_sampler() const noexcept { + [[nodiscard]] vk::Sampler get_vulkan_sampler() const noexcept { return sampler_; } /** * @brief 获取描述符图像信息 - * @param view 图像视图(可为 VK_NULL_HANDLE) + * @param view 图像视图(可为空) * @param layout 图像布局 - * @return VkDescriptorImageInfo 结构 + * @return vk::DescriptorImageInfo 结构 */ - [[nodiscard]] VkDescriptorImageInfo get_descriptor_info( - VkImageView view = VK_NULL_HANDLE, - VkImageLayout layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) const noexcept; + [[nodiscard]] vk::DescriptorImageInfo get_descriptor_info( + vk::ImageView view = {}, + vk::ImageLayout layout = vk::ImageLayout::eShaderReadOnlyOptimal) const noexcept; protected: /** @@ -327,10 +327,10 @@ private: void_result create_sampler(); /// Vulkan 设备 - VkDevice device_ = VK_NULL_HANDLE; + vk::Device device_; - /// VkSampler 句柄 - VkSampler sampler_ = VK_NULL_HANDLE; + /// vk::Sampler 句柄 + vk::Sampler sampler_; /// 采样器信息 sampler_info info_; @@ -364,7 +364,7 @@ public: * @brief 构造函数 * @param device Vulkan 设备 */ - explicit sampler_cache(VkDevice device); + explicit sampler_cache(vk::Device device); /** * @brief 析构函数 @@ -475,7 +475,7 @@ protected: private: /// Vulkan 设备 - VkDevice device_ = VK_NULL_HANDLE; + vk::Device device_; /// 采样器缓存 std::unordered_map> cache_; diff --git a/src/resource/texture.cpp b/src/resource/texture.cpp index d614721..e67830e 100644 --- a/src/resource/texture.cpp +++ b/src/resource/texture.cpp @@ -8,6 +8,7 @@ #include "texture.hpp" #include "texture_view.hpp" #include "logger.hpp" +#include "vulkan_types.hpp" #include @@ -24,7 +25,7 @@ texture::texture(std::shared_ptr allocator, const texture_info& i , current_layout_(info.initial_layout) { if (!allocator_) { - log_error("Texture created with null allocator"); + MILAI_LOG_ERROR("Texture created with null allocator"); return; } @@ -43,11 +44,11 @@ texture::texture(std::shared_ptr allocator, const texture_info& i auto result = create_image(); if (!result.has_value()) { - log_error("Failed to create texture: {}", result.error().message); + MILAI_LOG_ERROR("Failed to create texture: {}", result.error().message); } } -texture::texture(std::shared_ptr allocator, VkImage image, +texture::texture(std::shared_ptr allocator, vk::Image image, const texture_info& info, bool owns_image) : allocator_(std::move(allocator)) , image_(image) @@ -73,7 +74,7 @@ texture::texture(texture&& other) noexcept , current_layout_(other.current_layout_) { other.allocation_ = {}; - other.image_ = VK_NULL_HANDLE; + other.image_ = vk::Image{}; other.owns_image_ = false; } @@ -94,7 +95,7 @@ texture& texture::operator=(texture&& other) noexcept { // 清空源对象 other.allocation_ = {}; - other.image_ = VK_NULL_HANDLE; + other.image_ = vk::Image{}; other.owns_image_ = false; } return *this; @@ -108,18 +109,18 @@ void_result texture::create_image() { image_allocation_info alloc_info; alloc_info.image_type = to_vulkan_image_type(info_.type); alloc_info.format = to_vulkan_format(info_.format); - alloc_info.extent = {info_.width, info_.height, info_.depth}; + alloc_info.extent = vk::Extent3D{info_.width, info_.height, info_.depth}; alloc_info.mip_levels = info_.mip_levels; alloc_info.array_layers = info_.array_layers; alloc_info.samples = to_vulkan_sample_count(info_.samples); - alloc_info.tiling = VK_IMAGE_TILING_OPTIMAL; + alloc_info.tiling = vk::ImageTiling::eOptimal; alloc_info.usage = to_vulkan_image_usage(info_.usage); alloc_info.initial_layout = to_vulkan_image_layout(info_.initial_layout); alloc_info.mem_usage = info_.mem_usage; alloc_info.debug_name = info_.debug_name; // 立方体贴图标志 - alloc_info.is_cube = (info_.type == texture_type::texture_cube || + alloc_info.is_cube = (info_.type == texture_type::texture_cube || info_.type == texture_type::texture_cube_array); auto result = allocator_->allocate_image(alloc_info); @@ -186,29 +187,25 @@ result> texture::create_default_view() { // Mipmap 生成 // ================================================================================================ -void texture::generate_mipmaps(VkCommandBuffer cmd_buffer) { +void texture::generate_mipmaps(vk::CommandBuffer cmd_buffer) { if (!is_valid() || info_.mip_levels <= 1) { return; } - VkFormatProperties format_props; - vkGetPhysicalDeviceFormatProperties( - allocator_->get_physical_device(), - to_vulkan_format(info_.format), - &format_props); + vk::FormatProperties format_props = allocator_->get_physical_device().getFormatProperties( + to_vulkan_format(info_.format)); // 检查是否支持 blit - if (!(format_props.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT)) { + if (!(format_props.optimalTilingFeatures & vk::FormatFeatureFlagBits::eSampledImageFilterLinear)) { MILAI_LOG_WARN("Texture format does not support linear blitting for mipmap generation"); return; } - VkImageMemoryBarrier2 barrier{}; - barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2; + vk::ImageMemoryBarrier2 barrier{}; barrier.image = image_; barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; - barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + barrier.subresourceRange.aspectMask = vk::ImageAspectFlagBits::eColor; barrier.subresourceRange.baseArrayLayer = 0; barrier.subresourceRange.layerCount = info_.array_layers; barrier.subresourceRange.levelCount = 1; @@ -220,26 +217,24 @@ void texture::generate_mipmaps(VkCommandBuffer cmd_buffer) { for (u32 i = 1; i < info_.mip_levels; ++i) { // 转换上一级 mip 为传输源 barrier.subresourceRange.baseMipLevel = i - 1; - barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; - barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; - barrier.srcStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT; - barrier.srcAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT; - barrier.dstStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT; - barrier.dstAccessMask = VK_ACCESS_2_TRANSFER_READ_BIT; + barrier.oldLayout = vk::ImageLayout::eTransferDstOptimal; + barrier.newLayout = vk::ImageLayout::eTransferSrcOptimal; + barrier.srcStageMask = vk::PipelineStageFlagBits2::eTransfer; + barrier.srcAccessMask = vk::AccessFlagBits2::eTransferWrite; + barrier.dstStageMask = vk::PipelineStageFlagBits2::eTransfer; + barrier.dstAccessMask = vk::AccessFlagBits2::eTransferRead; - VkDependencyInfo dep_info{}; - dep_info.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO; + vk::DependencyInfo dep_info{}; dep_info.imageMemoryBarrierCount = 1; dep_info.pImageMemoryBarriers = &barrier; - vkCmdPipelineBarrier2(cmd_buffer, &dep_info); + cmd_buffer.pipelineBarrier2(dep_info); // Blit 到下一级 mip - VkImageBlit2 blit{}; - blit.sType = VK_STRUCTURE_TYPE_IMAGE_BLIT_2; - blit.srcOffsets[0] = {0, 0, 0}; - blit.srcOffsets[1] = {mip_width, mip_height, mip_depth}; - blit.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + vk::ImageBlit2 blit{}; + blit.srcOffsets[0] = vk::Offset3D{0, 0, 0}; + blit.srcOffsets[1] = vk::Offset3D{mip_width, mip_height, mip_depth}; + blit.srcSubresource.aspectMask = vk::ImageAspectFlagBits::eColor; blit.srcSubresource.mipLevel = i - 1; blit.srcSubresource.baseArrayLayer = 0; blit.srcSubresource.layerCount = info_.array_layers; @@ -248,34 +243,33 @@ void texture::generate_mipmaps(VkCommandBuffer cmd_buffer) { i32 next_height = mip_height > 1 ? mip_height / 2 : 1; i32 next_depth = mip_depth > 1 ? mip_depth / 2 : 1; - blit.dstOffsets[0] = {0, 0, 0}; - blit.dstOffsets[1] = {next_width, next_height, next_depth}; - blit.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + blit.dstOffsets[0] = vk::Offset3D{0, 0, 0}; + blit.dstOffsets[1] = vk::Offset3D{next_width, next_height, next_depth}; + blit.dstSubresource.aspectMask = vk::ImageAspectFlagBits::eColor; blit.dstSubresource.mipLevel = i; blit.dstSubresource.baseArrayLayer = 0; blit.dstSubresource.layerCount = info_.array_layers; - VkBlitImageInfo2 blit_info{}; - blit_info.sType = VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2; + vk::BlitImageInfo2 blit_info{}; blit_info.srcImage = image_; - blit_info.srcImageLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; + blit_info.srcImageLayout = vk::ImageLayout::eTransferSrcOptimal; blit_info.dstImage = image_; - blit_info.dstImageLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + blit_info.dstImageLayout = vk::ImageLayout::eTransferDstOptimal; blit_info.regionCount = 1; blit_info.pRegions = &blit; - blit_info.filter = VK_FILTER_LINEAR; + blit_info.filter = vk::Filter::eLinear; - vkCmdBlitImage2(cmd_buffer, &blit_info); + cmd_buffer.blitImage2(blit_info); // 转换上一级 mip 为着色器只读 - barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; - barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; - barrier.srcStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT; - barrier.srcAccessMask = VK_ACCESS_2_TRANSFER_READ_BIT; - barrier.dstStageMask = VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT; - barrier.dstAccessMask = VK_ACCESS_2_SHADER_READ_BIT; + barrier.oldLayout = vk::ImageLayout::eTransferSrcOptimal; + barrier.newLayout = vk::ImageLayout::eShaderReadOnlyOptimal; + barrier.srcStageMask = vk::PipelineStageFlagBits2::eTransfer; + barrier.srcAccessMask = vk::AccessFlagBits2::eTransferRead; + barrier.dstStageMask = vk::PipelineStageFlagBits2::eFragmentShader; + barrier.dstAccessMask = vk::AccessFlagBits2::eShaderRead; - vkCmdPipelineBarrier2(cmd_buffer, &dep_info); + cmd_buffer.pipelineBarrier2(dep_info); mip_width = next_width; mip_height = next_height; @@ -284,19 +278,18 @@ void texture::generate_mipmaps(VkCommandBuffer cmd_buffer) { // 转换最后一级 mip 为着色器只读 barrier.subresourceRange.baseMipLevel = info_.mip_levels - 1; - barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; - barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; - barrier.srcStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT; - barrier.srcAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT; - barrier.dstStageMask = VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT; - barrier.dstAccessMask = VK_ACCESS_2_SHADER_READ_BIT; + barrier.oldLayout = vk::ImageLayout::eTransferDstOptimal; + barrier.newLayout = vk::ImageLayout::eShaderReadOnlyOptimal; + barrier.srcStageMask = vk::PipelineStageFlagBits2::eTransfer; + barrier.srcAccessMask = vk::AccessFlagBits2::eTransferWrite; + barrier.dstStageMask = vk::PipelineStageFlagBits2::eFragmentShader; + barrier.dstAccessMask = vk::AccessFlagBits2::eShaderRead; - VkDependencyInfo dep_info{}; - dep_info.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO; + vk::DependencyInfo dep_info{}; dep_info.imageMemoryBarrierCount = 1; dep_info.pImageMemoryBarriers = &barrier; - vkCmdPipelineBarrier2(cmd_buffer, &dep_info); + cmd_buffer.pipelineBarrier2(dep_info); current_layout_ = image_layout::shader_read_only_optimal; } @@ -306,7 +299,7 @@ void texture::generate_mipmaps(VkCommandBuffer cmd_buffer) { // ================================================================================================ void texture::transition_layout( - VkCommandBuffer cmd_buffer, + vk::CommandBuffer cmd_buffer, image_layout old_layout, image_layout new_layout, image_aspect aspect, @@ -327,14 +320,13 @@ void texture::transition_layout( layer_count = info_.array_layers - base_array_layer; } - VkAccessFlags2 src_access, dst_access; - VkPipelineStageFlags2 src_stage, dst_stage; + vk::AccessFlags2 src_access, dst_access; + vk::PipelineStageFlags2 src_stage, dst_stage; get_layout_transition_info(old_layout, src_access, src_stage); get_layout_transition_info(new_layout, dst_access, dst_stage); - VkImageMemoryBarrier2 barrier{}; - barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2; + vk::ImageMemoryBarrier2 barrier{}; barrier.oldLayout = to_vulkan_image_layout(old_layout); barrier.newLayout = to_vulkan_image_layout(new_layout); barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; @@ -350,12 +342,11 @@ void texture::transition_layout( barrier.dstStageMask = dst_stage; barrier.dstAccessMask = dst_access; - VkDependencyInfo dep_info{}; - dep_info.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO; + vk::DependencyInfo dep_info{}; dep_info.imageMemoryBarrierCount = 1; dep_info.pImageMemoryBarriers = &barrier; - vkCmdPipelineBarrier2(cmd_buffer, &dep_info); + cmd_buffer.pipelineBarrier2(dep_info); // 更新当前布局(如果是全局转换) if (base_mip_level == 0 && mip_count == info_.mip_levels && @@ -364,7 +355,7 @@ void texture::transition_layout( } } -void texture::transition_layout(VkCommandBuffer cmd_buffer, image_layout new_layout) { +void texture::transition_layout(vk::CommandBuffer cmd_buffer, image_layout new_layout) { transition_layout(cmd_buffer, current_layout_, new_layout, get_default_aspect(info_.format), 0, 0, 0, 0); } @@ -373,8 +364,8 @@ void texture::transition_layout(VkCommandBuffer cmd_buffer, image_layout new_lay // 子资源范围 // ================================================================================================ -VkImageSubresourceRange texture::get_full_subresource_range() const noexcept { - VkImageSubresourceRange range{}; +vk::ImageSubresourceRange texture::get_full_subresource_range() const noexcept { + vk::ImageSubresourceRange range{}; range.aspectMask = to_vulkan_image_aspect(get_default_aspect(info_.format)); range.baseMipLevel = 0; range.levelCount = info_.mip_levels; @@ -383,14 +374,14 @@ VkImageSubresourceRange texture::get_full_subresource_range() const noexcept { return range; } -VkImageSubresourceRange texture::get_subresource_range( +vk::ImageSubresourceRange texture::get_subresource_range( image_aspect aspect, u32 base_mip_level, u32 mip_count, u32 base_array_layer, u32 layer_count) const noexcept { - VkImageSubresourceRange range{}; + vk::ImageSubresourceRange range{}; range.aspectMask = to_vulkan_image_aspect(aspect); range.baseMipLevel = base_mip_level; range.levelCount = (mip_count == 0) ? (info_.mip_levels - base_mip_level) : mip_count; @@ -405,14 +396,14 @@ VkImageSubresourceRange texture::get_subresource_range( void texture::on_created() { if (!info_.debug_name.empty()) { - log_debug("Texture '{}' created: {}x{}x{}, {} mip levels", + MILAI_LOG_DEBUG("Texture '{}' created: {}x{}x{}, {} mip levels", info_.debug_name, info_.width, info_.height, info_.depth, info_.mip_levels); } } void texture::on_destroying() { if (!info_.debug_name.empty()) { - log_debug("Texture '{}' destroying", info_.debug_name); + MILAI_LOG_DEBUG("Texture '{}' destroying", info_.debug_name); } } @@ -422,70 +413,70 @@ void texture::on_destroying() { void texture::get_layout_transition_info( image_layout layout, - VkAccessFlags2& access_mask, - VkPipelineStageFlags2& stage_mask) { + vk::AccessFlags2& access_mask, + vk::PipelineStageFlags2& stage_mask) { switch (layout) { case image_layout::undefined: - access_mask = VK_ACCESS_2_NONE; - stage_mask = VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT; + access_mask = vk::AccessFlagBits2::eNone; + stage_mask = vk::PipelineStageFlagBits2::eTopOfPipe; break; case image_layout::general: - access_mask = VK_ACCESS_2_SHADER_READ_BIT | VK_ACCESS_2_SHADER_WRITE_BIT; - stage_mask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT; + access_mask = vk::AccessFlagBits2::eShaderRead | vk::AccessFlagBits2::eShaderWrite; + stage_mask = vk::PipelineStageFlagBits2::eAllCommands; break; case image_layout::color_attachment_optimal: - access_mask = VK_ACCESS_2_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT; - stage_mask = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT; + access_mask = vk::AccessFlagBits2::eColorAttachmentRead | vk::AccessFlagBits2::eColorAttachmentWrite; + stage_mask = vk::PipelineStageFlagBits2::eColorAttachmentOutput; break; case image_layout::depth_stencil_attachment_optimal: - access_mask = VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT | - VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; - stage_mask = VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT | - VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT; + access_mask = vk::AccessFlagBits2::eDepthStencilAttachmentRead | + vk::AccessFlagBits2::eDepthStencilAttachmentWrite; + stage_mask = vk::PipelineStageFlagBits2::eEarlyFragmentTests | + vk::PipelineStageFlagBits2::eLateFragmentTests; break; case image_layout::depth_stencil_read_only_optimal: case image_layout::depth_read_only_optimal: case image_layout::stencil_read_only_optimal: - access_mask = VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT; - stage_mask = VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT | - VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT; + access_mask = vk::AccessFlagBits2::eDepthStencilAttachmentRead; + stage_mask = vk::PipelineStageFlagBits2::eEarlyFragmentTests | + vk::PipelineStageFlagBits2::eLateFragmentTests; break; case image_layout::shader_read_only_optimal: case image_layout::read_only_optimal: - access_mask = VK_ACCESS_2_SHADER_READ_BIT; - stage_mask = VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT | - VK_PIPELINE_STAGE_2_VERTEX_SHADER_BIT; + access_mask = vk::AccessFlagBits2::eShaderRead; + stage_mask = vk::PipelineStageFlagBits2::eFragmentShader | + vk::PipelineStageFlagBits2::eVertexShader; break; case image_layout::transfer_src_optimal: - access_mask = VK_ACCESS_2_TRANSFER_READ_BIT; - stage_mask = VK_PIPELINE_STAGE_2_TRANSFER_BIT; + access_mask = vk::AccessFlagBits2::eTransferRead; + stage_mask = vk::PipelineStageFlagBits2::eTransfer; break; case image_layout::transfer_dst_optimal: - access_mask = VK_ACCESS_2_TRANSFER_WRITE_BIT; - stage_mask = VK_PIPELINE_STAGE_2_TRANSFER_BIT; + access_mask = vk::AccessFlagBits2::eTransferWrite; + stage_mask = vk::PipelineStageFlagBits2::eTransfer; break; case image_layout::preinitialized: - access_mask = VK_ACCESS_2_HOST_WRITE_BIT; - stage_mask = VK_PIPELINE_STAGE_2_HOST_BIT; + access_mask = vk::AccessFlagBits2::eHostWrite; + stage_mask = vk::PipelineStageFlagBits2::eHost; break; case image_layout::present_src: - access_mask = VK_ACCESS_2_NONE; - stage_mask = VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT; + access_mask = vk::AccessFlagBits2::eNone; + stage_mask = vk::PipelineStageFlagBits2::eBottomOfPipe; break; default: - access_mask = VK_ACCESS_2_NONE; - stage_mask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT; + access_mask = vk::AccessFlagBits2::eNone; + stage_mask = vk::PipelineStageFlagBits2::eAllCommands; break; } } diff --git a/src/resource/texture.hpp b/src/resource/texture.hpp index 33048f5..654260a 100644 --- a/src/resource/texture.hpp +++ b/src/resource/texture.hpp @@ -16,8 +16,8 @@ #include "resource_types.hpp" #include "allocator.hpp" #include "object.hpp" +#include "vulkan_types.hpp" -#include #include namespace milai { @@ -223,13 +223,13 @@ public: texture(std::shared_ptr allocator, const texture_info& info); /** - * @brief 从现有 VkImage 创建(用于交换链图像等) + * @brief 从现有 vk::Image 创建(用于交换链图像等) * @param allocator GPU 分配器 - * @param image 现有的 VkImage + * @param image 现有的 vk::Image * @param info 纹理信息 * @param owns_image 是否拥有 Image(是否负责销毁) */ - texture(std::shared_ptr allocator, VkImage image, + texture(std::shared_ptr allocator, vk::Image image, const texture_info& info, bool owns_image = false); /** @@ -334,7 +334,7 @@ public: * @return 如果有效返回 true */ [[nodiscard]] bool is_valid() const noexcept { - return image_ != VK_NULL_HANDLE; + return image_; } /** @@ -396,13 +396,13 @@ public: /** * @brief 生成 mipmap - * + * * 使用 blit 操作生成所有 mip 层级。 * 需要纹理支持 transfer_src 和 transfer_dst 用途。 - * + * * @param cmd_buffer 命令缓冲区 */ - void generate_mipmaps(VkCommandBuffer cmd_buffer); + void generate_mipmaps(vk::CommandBuffer cmd_buffer); // ============================================================================================ // 布局转换 @@ -420,7 +420,7 @@ public: * @param layer_count 数组层数(0 表示所有) */ void transition_layout( - VkCommandBuffer cmd_buffer, + vk::CommandBuffer cmd_buffer, image_layout old_layout, image_layout new_layout, image_aspect aspect = image_aspect::color, @@ -434,7 +434,7 @@ public: * @param cmd_buffer 命令缓冲区 * @param new_layout 新布局 */ - void transition_layout(VkCommandBuffer cmd_buffer, image_layout new_layout); + void transition_layout(vk::CommandBuffer cmd_buffer, image_layout new_layout); // ============================================================================================ // Vulkan 句柄 @@ -442,9 +442,9 @@ public: /** * @brief 获取 Vulkan Image 句柄 - * @return VkImage 句柄 + * @return vk::Image 句柄 */ - [[nodiscard]] VkImage get_vulkan_image() const noexcept { + [[nodiscard]] vk::Image get_vulkan_image() const noexcept { return image_; } @@ -470,9 +470,9 @@ public: /** * @brief 获取完整的子资源范围 - * @return VkImageSubresourceRange 结构 + * @return vk::ImageSubresourceRange 结构 */ - [[nodiscard]] VkImageSubresourceRange get_full_subresource_range() const noexcept; + [[nodiscard]] vk::ImageSubresourceRange get_full_subresource_range() const noexcept; /** * @brief 获取子资源范围 @@ -481,9 +481,9 @@ public: * @param mip_count mip 层级数 * @param base_array_layer 基础数组层 * @param layer_count 数组层数 - * @return VkImageSubresourceRange 结构 + * @return vk::ImageSubresourceRange 结构 */ - [[nodiscard]] VkImageSubresourceRange get_subresource_range( + [[nodiscard]] vk::ImageSubresourceRange get_subresource_range( image_aspect aspect, u32 base_mip_level, u32 mip_count, @@ -516,8 +516,8 @@ private: */ static void get_layout_transition_info( image_layout layout, - VkAccessFlags2& access_mask, - VkPipelineStageFlags2& stage_mask); + vk::AccessFlags2& access_mask, + vk::PipelineStageFlags2& stage_mask); /// GPU 分配器 std::shared_ptr allocator_; @@ -525,8 +525,8 @@ private: /// VMA 分配 image_allocation allocation_; - /// VkImage 句柄 - VkImage image_ = VK_NULL_HANDLE; + /// vk::Image 句柄 + vk::Image image_; /// 纹理信息 texture_info info_; diff --git a/src/resource/texture_view.cpp b/src/resource/texture_view.cpp index 38dc358..9efcd8d 100644 --- a/src/resource/texture_view.cpp +++ b/src/resource/texture_view.cpp @@ -20,7 +20,7 @@ texture_view::texture_view(std::shared_ptr tex, const texture_view_info , info_(info) { if (!texture_ || !texture_->is_valid()) { - log_error("Texture view created with invalid texture"); + MILAI_LOG_ERROR("Texture view created with invalid texture"); return; } @@ -34,7 +34,7 @@ texture_view::texture_view(std::shared_ptr tex, const texture_view_info auto result = create_view(); if (!result.has_value()) { - log_error("Failed to create texture view: {}", result.error().message); + MILAI_LOG_ERROR("Failed to create texture view: {}", result.error().message); } } @@ -42,7 +42,7 @@ texture_view::texture_view(std::shared_ptr tex) : texture_(std::move(tex)) { if (!texture_ || !texture_->is_valid()) { - log_error("Texture view created with invalid texture"); + MILAI_LOG_ERROR("Texture view created with invalid texture"); return; } @@ -55,14 +55,14 @@ texture_view::texture_view(std::shared_ptr tex) auto result = create_view(); if (!result.has_value()) { - log_error("Failed to create texture view: {}", result.error().message); + MILAI_LOG_ERROR("Failed to create texture view: {}", result.error().message); } } texture_view::~texture_view() { - if (view_ != VK_NULL_HANDLE && texture_ && texture_->get_allocator()) { - vkDestroyImageView(texture_->get_allocator()->get_device(), view_, nullptr); - view_ = VK_NULL_HANDLE; + if (view_ && texture_ && texture_->get_allocator()) { + texture_->get_allocator()->get_device().destroyImageView(view_); + view_ = vk::ImageView{}; } } @@ -71,14 +71,14 @@ texture_view::texture_view(texture_view&& other) noexcept , view_(other.view_) , info_(std::move(other.info_)) { - other.view_ = VK_NULL_HANDLE; + other.view_ = vk::ImageView{}; } texture_view& texture_view::operator=(texture_view&& other) noexcept { if (this != &other) { // 释放当前资源 - if (view_ != VK_NULL_HANDLE && texture_ && texture_->get_allocator()) { - vkDestroyImageView(texture_->get_allocator()->get_device(), view_, nullptr); + if (view_ && texture_ && texture_->get_allocator()) { + texture_->get_allocator()->get_device().destroyImageView(view_); } // 移动资源 @@ -87,7 +87,7 @@ texture_view& texture_view::operator=(texture_view&& other) noexcept { info_ = std::move(other.info_); // 清空源对象 - other.view_ = VK_NULL_HANDLE; + other.view_ = vk::ImageView{}; } return *this; } @@ -106,8 +106,7 @@ void_result texture_view::create_view() { return make_void_error(error_code::null_pointer, "Texture allocator is null"); } - VkImageViewCreateInfo create_info{}; - create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; + vk::ImageViewCreateInfo create_info{}; create_info.image = texture_->get_vulkan_image(); create_info.viewType = to_vulkan_image_view_type(texture_->get_texture_type()); create_info.format = to_vulkan_format(texture_->get_format()); @@ -118,11 +117,12 @@ void_result texture_view::create_view() { create_info.subresourceRange.baseArrayLayer = info_.base_array_layer; create_info.subresourceRange.layerCount = info_.array_layer_count; - VkResult result = vkCreateImageView(allocator->get_device(), &create_info, nullptr, &view_); - if (result != VK_SUCCESS) { + auto [result, view] = allocator->get_device().createImageView(create_info); + if (result != vk::Result::eSuccess) { return make_void_error(error_code::vulkan_init_failed, - "Failed to create image view: " + std::to_string(result)); + "Failed to create image view: " + vk::to_string(result)); } + view_ = view; return make_success(); } @@ -131,22 +131,22 @@ void_result texture_view::create_view() { // Vulkan 句柄 // ================================================================================================ -VkImage texture_view::get_vulkan_image() const noexcept { +vk::Image texture_view::get_vulkan_image() const noexcept { if (texture_) { return texture_->get_vulkan_image(); } - return VK_NULL_HANDLE; + return vk::Image{}; } // ================================================================================================ // 描述符信息 // ================================================================================================ -VkDescriptorImageInfo texture_view::get_descriptor_info( - VkSampler sampler, - VkImageLayout image_layout) const noexcept { +vk::DescriptorImageInfo texture_view::get_descriptor_info( + vk::Sampler sampler, + vk::ImageLayout image_layout) const noexcept { - VkDescriptorImageInfo info{}; + vk::DescriptorImageInfo info{}; info.sampler = sampler; info.imageView = view_; info.imageLayout = image_layout; @@ -157,8 +157,8 @@ VkDescriptorImageInfo texture_view::get_descriptor_info( // 子资源范围 // ================================================================================================ -VkImageSubresourceRange texture_view::get_subresource_range() const noexcept { - VkImageSubresourceRange range{}; +vk::ImageSubresourceRange texture_view::get_subresource_range() const noexcept { + vk::ImageSubresourceRange range{}; range.aspectMask = to_vulkan_image_aspect(info_.aspect); range.baseMipLevel = info_.base_mip_level; range.levelCount = info_.mip_level_count; @@ -173,13 +173,13 @@ VkImageSubresourceRange texture_view::get_subresource_range() const noexcept { void texture_view::on_created() { if (!info_.debug_name.empty()) { - log_debug("Texture view '{}' created", info_.debug_name); + MILAI_LOG_DEBUG("Texture view '{}' created", info_.debug_name); } } void texture_view::on_destroying() { if (!info_.debug_name.empty()) { - log_debug("Texture view '{}' destroying", info_.debug_name); + MILAI_LOG_DEBUG("Texture view '{}' destroying", info_.debug_name); } } diff --git a/src/resource/texture_view.hpp b/src/resource/texture_view.hpp index 4abdd94..8d635ce 100644 --- a/src/resource/texture_view.hpp +++ b/src/resource/texture_view.hpp @@ -14,8 +14,8 @@ #include "resource_types.hpp" #include "object.hpp" +#include "vulkan_types.hpp" -#include #include namespace milai { @@ -46,11 +46,11 @@ struct texture_view_info { /// 数组层数(0 表示所有剩余层) u32 array_layer_count = 0; /// 组件映射 - VkComponentMapping component_mapping = { - VK_COMPONENT_SWIZZLE_IDENTITY, - VK_COMPONENT_SWIZZLE_IDENTITY, - VK_COMPONENT_SWIZZLE_IDENTITY, - VK_COMPONENT_SWIZZLE_IDENTITY + vk::ComponentMapping component_mapping = { + vk::ComponentSwizzle::eIdentity, + vk::ComponentSwizzle::eIdentity, + vk::ComponentSwizzle::eIdentity, + vk::ComponentSwizzle::eIdentity }; /// 调试名称 std::string debug_name; @@ -177,7 +177,7 @@ public: * @return 如果有效返回 true */ [[nodiscard]] bool is_valid() const noexcept { - return view_ != VK_NULL_HANDLE; + return view_; } /** @@ -194,17 +194,17 @@ public: /** * @brief 获取 Vulkan Image View 句柄 - * @return VkImageView 句柄 + * @return vk::ImageView 句柄 */ - [[nodiscard]] VkImageView get_vulkan_view() const noexcept { + [[nodiscard]] vk::ImageView get_vulkan_view() const noexcept { return view_; } /** * @brief 获取 Vulkan Image 句柄(来自关联纹理) - * @return VkImage 句柄 + * @return vk::Image 句柄 */ - [[nodiscard]] VkImage get_vulkan_image() const noexcept; + [[nodiscard]] vk::Image get_vulkan_image() const noexcept; // ============================================================================================ // 描述符信息 @@ -212,13 +212,13 @@ public: /** * @brief 获取描述符图像信息 - * @param sampler 采样器(可为 VK_NULL_HANDLE) + * @param sampler 采样器(可为空) * @param image_layout 图像布局 - * @return VkDescriptorImageInfo 结构 + * @return vk::DescriptorImageInfo 结构 */ - [[nodiscard]] VkDescriptorImageInfo get_descriptor_info( - VkSampler sampler = VK_NULL_HANDLE, - VkImageLayout image_layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) const noexcept; + [[nodiscard]] vk::DescriptorImageInfo get_descriptor_info( + vk::Sampler sampler = {}, + vk::ImageLayout image_layout = vk::ImageLayout::eShaderReadOnlyOptimal) const noexcept; // ============================================================================================ // 子资源范围 @@ -226,9 +226,9 @@ public: /** * @brief 获取视图的子资源范围 - * @return VkImageSubresourceRange 结构 + * @return vk::ImageSubresourceRange 结构 */ - [[nodiscard]] VkImageSubresourceRange get_subresource_range() const noexcept; + [[nodiscard]] vk::ImageSubresourceRange get_subresource_range() const noexcept; protected: /** @@ -251,8 +251,8 @@ private: /// 关联的纹理 std::shared_ptr texture_; - /// VkImageView 句柄 - VkImageView view_ = VK_NULL_HANDLE; + /// vk::ImageView 句柄 + vk::ImageView view_; /// 视图信息 texture_view_info info_; diff --git a/src/shader/CMakeLists.txt b/src/shader/CMakeLists.txt index 75944c9..3bda2f4 100644 --- a/src/shader/CMakeLists.txt +++ b/src/shader/CMakeLists.txt @@ -5,7 +5,7 @@ project(milai_shader) simple_library(STATIC) -target_link_libraries(${PROJECT_NAME} PUBLIC milai_core milai_resource Vulkan::Vulkan) +target_link_libraries(${PROJECT_NAME} PUBLIC milai_core milai_render milai_resource Vulkan::Vulkan) set_target_properties(${PROJECT_NAME} PROPERTIES VERSION ${PROJECT_VERSION} SOVERSION ${PROJECT_VERSION_MAJOR} diff --git a/src/shader/shader_cache.cpp b/src/shader/shader_cache.cpp index 63cc2e0..b420ddb 100644 --- a/src/shader/shader_cache.cpp +++ b/src/shader/shader_cache.cpp @@ -123,10 +123,10 @@ std::optional shader_cache::get_by_key(std::string_view key) // 在磁盘缓存中查找 if (config_.enable_disk_cache) { auto entry = load_entry_from_disk(key); - if (entry && !is_expired(*entry)) { + if (entry.has_value() && !is_expired(entry.value())) { // 加载到内存缓存 if (config_.enable_memory_cache) { - memory_cache_[std::string(key)] = *entry; + memory_cache_.insert_or_assign(std::string(key), entry.value()); } ++stats_.hits; return entry; @@ -421,8 +421,8 @@ u32 shader_cache::load_from_disk() { std::string key = filename.substr(0, filename.size() - 4); auto entry = load_entry_from_disk(key); - if (entry && !is_expired(*entry)) { - memory_cache_[key] = std::move(*entry); + if (entry.has_value() && !is_expired(entry.value())) { + memory_cache_.insert_or_assign(key, std::move(entry.value())); ++loaded; } } diff --git a/src/shader/shader_module.cpp b/src/shader/shader_module.cpp index 93913a9..32605c7 100644 --- a/src/shader/shader_module.cpp +++ b/src/shader/shader_module.cpp @@ -6,8 +6,8 @@ */ #include "shader_module.hpp" +#include "vulkan_types.hpp" -#include #include namespace milai { @@ -22,43 +22,11 @@ shader_module::~shader_module() { destroy(); } -shader_module::shader_module(shader_module&& other) noexcept - : object(std::move(other)) - , device_(other.device_) - , module_(other.module_) - , stage_(other.stage_) - , entry_point_(std::move(other.entry_point_)) - , spirv_(std::move(other.spirv_)) - , reflection_(std::move(other.reflection_)) - , source_path_(std::move(other.source_path_)) { - other.device_ = nullptr; - other.module_ = nullptr; -} - -shader_module& shader_module::operator=(shader_module&& other) noexcept { - if (this != &other) { - destroy(); - - object::operator=(std::move(other)); - device_ = other.device_; - module_ = other.module_; - stage_ = other.stage_; - entry_point_ = std::move(other.entry_point_); - spirv_ = std::move(other.spirv_); - reflection_ = std::move(other.reflection_); - source_path_ = std::move(other.source_path_); - - other.device_ = nullptr; - other.module_ = nullptr; - } - return *this; -} - std::unique_ptr shader_module::create( - VkDevice device, + vk::Device device, const shader_module_create_info& create_info) { - if (device == nullptr) { + if (!device) { return nullptr; } @@ -76,7 +44,7 @@ std::unique_ptr shader_module::create( } std::unique_ptr shader_module::create_from_spirv( - VkDevice device, + vk::Device device, std::span spirv, shader_stage stage, std::string_view entry_point) { @@ -90,54 +58,49 @@ std::unique_ptr shader_module::create_from_spirv( } std::unique_ptr shader_module::create_from_binary( - VkDevice device, + vk::Device device, const shader_binary& binary) { return create(device, shader_module_create_info::from_binary(binary)); } -bool shader_module::initialize(VkDevice device, const shader_module_create_info& create_info) { +bool shader_module::initialize(vk::Device device, const shader_module_create_info& create_info) { device_ = device; stage_ = create_info.stage; entry_point_ = create_info.entry_point; spirv_ = create_info.spirv; source_path_ = create_info.source_path; - + + #if MILAI_DEBUG if (!create_info.name.empty()) { - set_name(create_info.name); + set_debug_name(create_info.name); } + #endif // 创建 Vulkan 着色器模块 - VkShaderModuleCreateInfo module_info{}; - module_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; + vk::ShaderModuleCreateInfo module_info{}; module_info.codeSize = spirv_.size() * sizeof(u32); module_info.pCode = spirv_.data(); - VkResult result = vkCreateShaderModule(device_, &module_info, nullptr, &module_); + auto [result, mod] = device_.createShaderModule(module_info); - if (result != VK_SUCCESS) { + if (result != vk::Result::eSuccess) { return false; } + module_ = mod; // 设置 Vulkan 对象调试名称 -#ifdef VK_EXT_debug_utils - if (!get_name().empty()) { - VkDebugUtilsObjectNameInfoEXT name_info{}; - name_info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT; - name_info.objectType = VK_OBJECT_TYPE_SHADER_MODULE; - name_info.objectHandle = reinterpret_cast(module_); - name_info.pObjectName = get_name().c_str(); + #if MILAI_DEBUG && defined(VK_EXT_debug_utils) + if (!get_debug_name().empty()) { + vk::DebugUtilsObjectNameInfoEXT name_info{}; + name_info.objectType = vk::ObjectType::eShaderModule; + name_info.objectHandle = reinterpret_cast(static_cast(module_)); + name_info.pObjectName = get_debug_name().c_str(); // 注意:需要设备支持 VK_EXT_debug_utils 扩展 - // 这里使用动态加载或忽略错误 - auto func = reinterpret_cast( - vkGetDeviceProcAddr(device_, "vkSetDebugUtilsObjectNameEXT") - ); - if (func != nullptr) { - func(device_, &name_info); - } + device_.setDebugUtilsObjectNameEXT(name_info); } -#endif + #endif // 执行反射 if (!reflection_.reflect(spirv_)) { @@ -149,11 +112,11 @@ bool shader_module::initialize(VkDevice device, const shader_module_create_info& } void shader_module::destroy() { - if (module_ != nullptr && device_ != nullptr) { - vkDestroyShaderModule(device_, module_, nullptr); - module_ = nullptr; + if (module_ && device_) { + device_.destroyShaderModule(module_); + module_ = vk::ShaderModule{}; } - device_ = nullptr; + device_ = vk::Device{}; spirv_.clear(); } diff --git a/src/shader/shader_module.hpp b/src/shader/shader_module.hpp index 5a5dc82..2be6fe9 100644 --- a/src/shader/shader_module.hpp +++ b/src/shader/shader_module.hpp @@ -15,6 +15,8 @@ #include "shader_reflection.hpp" #include "object.hpp" +#include "vulkan_types.hpp" + #include #include #include @@ -22,10 +24,6 @@ #include #include -// 前向声明 Vulkan 类型 -typedef struct VkShaderModule_T* VkShaderModule; -typedef struct VkDevice_T* VkDevice; - namespace milai { /** @@ -89,6 +87,8 @@ struct shader_module_create_info { */ class shader_module : public object { public: + MILAI_OBJECT_TYPE_INFO(shader_module, object); + /** * @brief 创建着色器模块 * @param device Vulkan 设备 @@ -96,7 +96,7 @@ public: * @return 着色器模块指针,失败返回 nullptr */ [[nodiscard]] static std::unique_ptr create( - VkDevice device, + vk::Device device, const shader_module_create_info& create_info ); @@ -109,7 +109,7 @@ public: * @return 着色器模块指针 */ [[nodiscard]] static std::unique_ptr create_from_spirv( - VkDevice device, + vk::Device device, std::span spirv, shader_stage stage, std::string_view entry_point = "main" @@ -122,7 +122,7 @@ public: * @return 着色器模块指针 */ [[nodiscard]] static std::unique_ptr create_from_binary( - VkDevice device, + vk::Device device, const shader_binary& binary ); @@ -130,23 +130,7 @@ public: * @brief 析构函数 */ ~shader_module() override; - - // 禁用拷贝 - shader_module(const shader_module&) = delete; - shader_module& operator=(const shader_module&) = delete; - - // 允许移动 - shader_module(shader_module&& other) noexcept; - shader_module& operator=(shader_module&& other) noexcept; - - /** - * @brief 获取对象类型名称 - * @return 类型名称 - */ - [[nodiscard]] std::string_view get_type_name() const noexcept override { - return "shader_module"; - } - + /** * @brief 获取着色器阶段 * @return 着色器阶段 @@ -177,9 +161,9 @@ public: /** * @brief 获取 Vulkan 模块句柄 - * @return VkShaderModule 句柄 + * @return vk::ShaderModule 句柄 */ - [[nodiscard]] VkShaderModule get_vulkan_module() const noexcept { return module_; } + [[nodiscard]] vk::ShaderModule get_vulkan_module() const noexcept { return module_; } /** * @brief 获取源文件路径 @@ -199,8 +183,8 @@ public: * @brief 检查模块是否有效 * @return 是否有效 */ - [[nodiscard]] bool is_valid() const noexcept { - return module_ != nullptr && reflection_.is_valid(); + [[nodiscard]] bool is_valid() const noexcept { + return module_ && reflection_.is_valid(); } /** @@ -283,7 +267,7 @@ protected: * @param create_info 创建信息 * @return 是否成功 */ - bool initialize(VkDevice device, const shader_module_create_info& create_info); + bool initialize(vk::Device device, const shader_module_create_info& create_info); /** * @brief 销毁 Vulkan 资源 @@ -292,10 +276,10 @@ protected: private: /// Vulkan 设备 - VkDevice device_{nullptr}; + vk::Device device_; /// Vulkan 着色器模块 - VkShaderModule module_{nullptr}; + vk::ShaderModule module_; /// 着色器阶段 shader_stage stage_{shader_stage::vertex}; diff --git a/src/shader/shader_program.cpp b/src/shader/shader_program.cpp index b31dfb2..02a978b 100644 --- a/src/shader/shader_program.cpp +++ b/src/shader/shader_program.cpp @@ -24,32 +24,6 @@ shader_program::~shader_program() { modules_.clear(); } -shader_program::shader_program(shader_program&& other) noexcept - : object(std::move(other)) - , device_(other.device_) - , modules_(std::move(other.modules_)) - , combined_reflection_(std::move(other.combined_reflection_)) - , layout_info_(std::move(other.layout_info_)) - , valid_(other.valid_) { - other.device_ = nullptr; - other.valid_ = false; -} - -shader_program& shader_program::operator=(shader_program&& other) noexcept { - if (this != &other) { - object::operator=(std::move(other)); - device_ = other.device_; - modules_ = std::move(other.modules_); - combined_reflection_ = std::move(other.combined_reflection_); - layout_info_ = std::move(other.layout_info_); - valid_ = other.valid_; - - other.device_ = nullptr; - other.valid_ = false; - } - return *this; -} - std::unique_ptr shader_program::create( VkDevice device, const shader_program_create_info& create_info) { @@ -91,10 +65,12 @@ std::unique_ptr shader_program::create_compute( bool shader_program::initialize(VkDevice device, const shader_program_create_info& create_info) { device_ = device; - + + #if MILAI_DEBUG if (!create_info.name.empty()) { - set_name(create_info.name); + set_debug_name(create_info.name); } + #endif // 添加所有提供的模块 if (create_info.vertex_shader != nullptr) { diff --git a/src/shader/shader_program.hpp b/src/shader/shader_program.hpp index 800b065..cd98c99 100644 --- a/src/shader/shader_program.hpp +++ b/src/shader/shader_program.hpp @@ -135,6 +135,8 @@ struct shader_program_create_info { */ class shader_program : public object { public: + MILAI_OBJECT_TYPE_INFO(shader_program, shader_program); + /** * @brief 创建着色器程序 * @param device Vulkan 设备 @@ -178,23 +180,7 @@ public: * @brief 析构函数 */ ~shader_program() override; - - // 禁用拷贝 - shader_program(const shader_program&) = delete; - shader_program& operator=(const shader_program&) = delete; - - // 允许移动 - shader_program(shader_program&& other) noexcept; - shader_program& operator=(shader_program&& other) noexcept; - - /** - * @brief 获取对象类型名称 - * @return 类型名称 - */ - [[nodiscard]] std::string_view get_type_name() const noexcept override { - return "shader_program"; - } - + /** * @brief 添加着色器模块 * @param module 着色器模块 diff --git a/src/text/font.cpp b/src/text/font.cpp index 51cd6f5..e254095 100644 --- a/src/text/font.cpp +++ b/src/text/font.cpp @@ -28,34 +28,6 @@ font::~font() { on_destroying(); } -font::font(font&& other) noexcept - : object(std::move(other)) - , face_(other.face_) - , font_data_(std::move(other.font_data_)) - , current_size_(other.current_size_) - , cached_style_(other.cached_style_) - , cached_weight_(other.cached_weight_) { - other.face_ = nullptr; - other.current_size_ = 0.0f; -} - -font& font::operator=(font&& other) noexcept { - if (this != &other) { - on_destroying(); - - object::operator=(std::move(other)); - face_ = other.face_; - font_data_ = std::move(other.font_data_); - current_size_ = other.current_size_; - cached_style_ = other.cached_style_; - cached_weight_ = other.cached_weight_; - - other.face_ = nullptr; - other.current_size_ = 0.0f; - } - return *this; -} - void font::on_created() { // 初始化时检测样式和字重 if (face_) { @@ -181,7 +153,7 @@ font_metrics font::get_metrics(f32 size) const { // 设置字体大小 FT_Error error = FT_Set_Char_Size(face_, 0, static_cast(size * 64.0f), 72, 72); if (error) { - LOG_ERROR("Failed to set font size: {}", size); + MILAI_LOG_ERROR("Failed to set font size: {}", size); return metrics; } current_size_ = size; @@ -263,7 +235,7 @@ f32 font::get_glyph_advance(u32 glyph_id, f32 size) const { if (std::abs(current_size_ - size) > 0.001f) { FT_Error error = FT_Set_Char_Size(face_, 0, static_cast(size * 64.0f), 72, 72); if (error) { - LOG_ERROR("Failed to set font size: {}", size); + MILAI_LOG_ERROR("Failed to set font size: {}", size); return 0.0f; } current_size_ = size; @@ -315,7 +287,7 @@ glyph_metrics font::get_glyph_metrics(u32 glyph_id, f32 size) const { if (std::abs(current_size_ - size) > 0.001f) { FT_Error error = FT_Set_Char_Size(face_, 0, static_cast(size * 64.0f), 72, 72); if (error) { - LOG_ERROR("Failed to set font size: {}", size); + MILAI_LOG_ERROR("Failed to set font size: {}", size); return metrics; } current_size_ = size; @@ -369,7 +341,7 @@ bool font::set_size(f32 size) { FT_Error error = FT_Set_Char_Size(face_, 0, static_cast(size * 64.0f), 72, 72); if (error) { - LOG_ERROR("Failed to set font size: {}", size); + MILAI_LOG_ERROR("Failed to set font size: {}", size); return false; } diff --git a/src/text/font.hpp b/src/text/font.hpp index 151506b..37fb10b 100644 --- a/src/text/font.hpp +++ b/src/text/font.hpp @@ -158,15 +158,7 @@ public: * @brief 析构函数 */ ~font() override; - - // 禁止拷贝 - font(const font&) = delete; - font& operator=(const font&) = delete; - - // 允许移动 - font(font&& other) noexcept; - font& operator=(font&& other) noexcept; - + // ============================================================================================ // 字体信息 // ============================================================================================ diff --git a/src/text/font_manager.cpp b/src/text/font_manager.cpp index 67e803f..2c1b03a 100644 --- a/src/text/font_manager.cpp +++ b/src/text/font_manager.cpp @@ -71,7 +71,7 @@ font_manager& font_manager::operator=(font_manager&& other) noexcept { void font_manager::on_created() { if (!initialize_freetype()) { - LOG_ERROR("Failed to initialize FreeType library"); + MILAI_LOG_ERROR("Failed to initialize FreeType library"); } } @@ -100,12 +100,12 @@ bool font_manager::initialize_freetype() { FT_Error error = FT_Init_FreeType(&library_); if (error) { - LOG_ERROR("Failed to initialize FreeType: error code {}", error); + MILAI_LOG_ERROR("Failed to initialize FreeType: error code {}", error); library_ = nullptr; return false; } - LOG_INFO("FreeType library initialized successfully"); + MILAI_LOG_INFO("FreeType library initialized successfully"); return true; } @@ -113,7 +113,7 @@ void font_manager::shutdown_freetype() { if (library_) { FT_Done_FreeType(library_); library_ = nullptr; - LOG_INFO("FreeType library shutdown"); + MILAI_LOG_INFO("FreeType library shutdown"); } } @@ -125,7 +125,7 @@ std::shared_ptr font_manager::load_font(const std::filesystem::path& path, std::lock_guard lock(mutex_); if (!library_) { - LOG_ERROR("Font manager not initialized"); + MILAI_LOG_ERROR("Font manager not initialized"); return nullptr; } @@ -142,14 +142,14 @@ std::shared_ptr font_manager::load_font(const std::filesystem::path& path, // 检查文件是否存在 if (!std::filesystem::exists(path)) { - LOG_ERROR("Font file not found: {}", path.string()); + MILAI_LOG_ERROR("Font file not found: {}", path.string()); return nullptr; } // 读取文件内容 std::ifstream file(path, std::ios::binary | std::ios::ate); if (!file) { - LOG_ERROR("Failed to open font file: {}", path.string()); + MILAI_LOG_ERROR("Failed to open font file: {}", path.string()); return nullptr; } @@ -158,7 +158,7 @@ std::shared_ptr font_manager::load_font(const std::filesystem::path& path, std::vector font_data(static_cast(file_size)); if (!file.read(reinterpret_cast(font_data.data()), file_size)) { - LOG_ERROR("Failed to read font file: {}", path.string()); + MILAI_LOG_ERROR("Failed to read font file: {}", path.string()); return nullptr; } file.close(); @@ -174,14 +174,14 @@ std::shared_ptr font_manager::load_font(const std::filesystem::path& path, ); if (error) { - LOG_ERROR("Failed to load font face from {}: error code {}", path.string(), error); + MILAI_LOG_ERROR("Failed to load font face from {}: error code {}", path.string(), error); return nullptr; } // 选择 Unicode 字符映射 error = FT_Select_Charmap(face, FT_ENCODING_UNICODE); if (error) { - LOG_WARNING("Font {} does not have Unicode charmap, using default", path.string()); + MILAI_LOG_WARN("Font {} does not have Unicode charmap, using default", path.string()); } // 创建字体对象 @@ -190,7 +190,7 @@ std::shared_ptr font_manager::load_font(const std::filesystem::path& path, // 添加到缓存 font_cache_[cache_key] = new_font; - LOG_INFO("Loaded font: {} ({})", new_font->get_full_name(), path.string()); + MILAI_LOG_INFO("Loaded font: {} ({})", new_font->get_full_name(), path.string()); return new_font; } @@ -205,12 +205,12 @@ std::shared_ptr font_manager::load_font_from_memory(std::vector data, std::lock_guard lock(mutex_); if (!library_) { - LOG_ERROR("Font manager not initialized"); + MILAI_LOG_ERROR("Font manager not initialized"); return nullptr; } if (data.empty()) { - LOG_ERROR("Empty font data"); + MILAI_LOG_ERROR("Empty font data"); return nullptr; } @@ -225,20 +225,20 @@ std::shared_ptr font_manager::load_font_from_memory(std::vector data, ); if (error) { - LOG_ERROR("Failed to load font face from memory: error code {}", error); + MILAI_LOG_ERROR("Failed to load font face from memory: error code {}", error); return nullptr; } // 选择 Unicode 字符映射 error = FT_Select_Charmap(face, FT_ENCODING_UNICODE); if (error) { - LOG_WARNING("Font does not have Unicode charmap, using default"); + MILAI_LOG_WARN("Font does not have Unicode charmap, using default"); } // 创建字体对象(移动数据) auto new_font = make_object(face, std::move(data)); - LOG_INFO("Loaded font from memory: {}", new_font->get_full_name()); + MILAI_LOG_INFO("Loaded font from memory: {}", new_font->get_full_name()); return new_font; } @@ -307,7 +307,7 @@ std::shared_ptr font_manager::get_font(const font_query& query) { } } - LOG_WARNING("Font not found: {} (weight={}, style={})", + MILAI_LOG_WARN("Font not found: {} (weight={}, style={})", query.family.value(), static_cast(query.weight.value_or(font_weight::regular)), static_cast(query.style.value_or(font_style::normal))); @@ -500,11 +500,11 @@ void font_manager::scan_system_fonts() { } } } catch (const std::exception& e) { - LOG_WARNING("Error scanning font directory {}: {}", dir.string(), e.what()); + MILAI_LOG_WARN("Error scanning font directory {}: {}", dir.string(), e.what()); } } - LOG_INFO("Found {} system fonts", system_fonts_.size()); + MILAI_LOG_INFO("Found {} system fonts", system_fonts_.size()); } std::vector font_manager::get_font_directories() const { diff --git a/src/text/glyph_atlas.cpp b/src/text/glyph_atlas.cpp index d6991c0..de6add8 100644 --- a/src/text/glyph_atlas.cpp +++ b/src/text/glyph_atlas.cpp @@ -296,7 +296,7 @@ const atlas_glyph_entry* glyph_atlas::add_glyph( atlas_region region; if (!allocate_region(padded_width, padded_height, region)) { - LOG_ERROR("Failed to allocate region for glyph {}:{}", font_ptr->id(), glyph_id); + MILAI_LOG_ERROR("Failed to allocate region for glyph {}:{}", font_ptr->id(), glyph_id); return nullptr; } @@ -585,7 +585,7 @@ void glyph_atlas::rebuild() { // 重新添加字形 // 注意:这里需要字形缓存的配合,暂时简化处理 - LOG_WARNING("Glyph atlas rebuild is not fully implemented"); + MILAI_LOG_WARN("Glyph atlas rebuild is not fully implemented"); } // ================================================================================================ @@ -594,7 +594,7 @@ void glyph_atlas::rebuild() { u32 glyph_atlas::create_page() { if (pages_.size() >= config_.max_pages) { - LOG_ERROR("Maximum number of atlas pages reached"); + MILAI_LOG_ERROR("Maximum number of atlas pages reached"); return UINT32_MAX; } @@ -604,14 +604,14 @@ u32 glyph_atlas::create_page() { // 创建 GPU 纹理 if (!create_gpu_texture(*page)) { - LOG_ERROR("Failed to create GPU texture for atlas page"); + MILAI_LOG_ERROR("Failed to create GPU texture for atlas page"); return UINT32_MAX; } u32 page_index = static_cast(pages_.size()); pages_.push_back(std::move(page)); - LOG_INFO("Created atlas page {} ({}x{})", page_index, current_width_, current_height_); + MILAI_LOG_INFO("Created atlas page {} ({}x{})", page_index, current_width_, current_height_); return page_index; } @@ -622,7 +622,7 @@ bool glyph_atlas::expand_pages(u32 new_width, u32 new_height) { } // 扩展现有页面需要重建,目前简化处理 - LOG_WARNING("Atlas page expansion not implemented, creating new page instead"); + MILAI_LOG_WARNING("Atlas page expansion not implemented, creating new page instead"); return create_page() != UINT32_MAX; } @@ -715,10 +715,10 @@ bool glyph_atlas::create_gpu_texture(atlas_page& page) { info.debug_name = "GlyphAtlasPage"; auto gpu_allocator = std::make_shared(device, allocator); - page.gpu_texture = make_object(gpu_allocator, info); + page.gpu_texture = make_obj(gpu_allocator, info); if (!page.gpu_texture || !page.gpu_texture->is_valid()) { - LOG_ERROR("Failed to create atlas texture"); + MILAI_LOG_ERROR("Failed to create atlas texture"); return false; } @@ -737,7 +737,7 @@ void glyph_atlas::update_gpu_texture(atlas_page& page) { // 然后执行内存复制和布局转换 // 由于实际实现需要更多的渲染器上下文支持,这里只标记为需要更新 - LOG_DEBUG("Atlas page texture update requested ({}x{}, {} bytes)", + MILAI_LOG_DEBUG("Atlas page texture update requested ({}x{}, {} bytes)", page.width, page.height, page.data.size()); } diff --git a/src/text/glyph_cache.cpp b/src/text/glyph_cache.cpp index ea77d4e..427e9f2 100644 --- a/src/text/glyph_cache.cpp +++ b/src/text/glyph_cache.cpp @@ -518,14 +518,14 @@ glyph_bitmap glyph_cache::generate_bitmap( // 设置字体大小 FT_Error error = FT_Set_Char_Size(face, 0, static_cast(size * 64.0f), 72, 72); if (error) { - LOG_ERROR("Failed to set font size for bitmap generation"); + MILAI_LOG_ERROR("Failed to set font size for bitmap generation"); return result; } // 加载字形 error = FT_Load_Glyph(face, glyph_id, FT_LOAD_RENDER); if (error) { - LOG_ERROR("Failed to load glyph {} for bitmap generation", glyph_id); + MILAI_LOG_ERROR("Failed to load glyph {} for bitmap generation", glyph_id); return result; } @@ -571,7 +571,7 @@ glyph_bitmap glyph_cache::generate_bitmap( } } } else { - LOG_WARNING("Unsupported bitmap pixel mode: {}", static_cast(bitmap.pixel_mode)); + MILAI_LOG_WARN("Unsupported bitmap pixel mode: {}", static_cast(bitmap.pixel_mode)); return glyph_bitmap{}; } diff --git a/src/text/text_shaper.cpp b/src/text/text_shaper.cpp index d3ce3b4..147d4e7 100644 --- a/src/text/text_shaper.cpp +++ b/src/text/text_shaper.cpp @@ -72,7 +72,7 @@ std::pair shaping_result::hit_test_x(f32 x) const { text_shaper::text_shaper() { buffer_ = hb_buffer_create(); if (!hb_buffer_allocation_successful(buffer_)) { - LOG_ERROR("Failed to create HarfBuzz buffer"); + MILAI_LOG_ERROR("Failed to create HarfBuzz buffer"); hb_buffer_destroy(buffer_); buffer_ = nullptr; } @@ -145,7 +145,7 @@ shaping_result text_shaper::shape( // 获取 HarfBuzz 字体 hb_font_t* hb_font = get_hb_font(font_ptr, size); if (!hb_font) { - LOG_ERROR("Failed to get HarfBuzz font"); + MILAI_LOG_ERROR("Failed to get HarfBuzz font"); return result; } @@ -542,7 +542,7 @@ hb_font_t* text_shaper::get_hb_font(const std::shared_ptr& font_ptr, f32 s // 创建 HarfBuzz 字体 hb_font_t* hb_font = hb_ft_font_create_referenced(ft_face); if (!hb_font) { - LOG_ERROR("Failed to create HarfBuzz font from FreeType face"); + MILAI_LOG_ERROR("Failed to create HarfBuzz font from FreeType face"); return nullptr; } diff --git a/tests/core/test_logger.cpp b/tests/core/test_logger.cpp index a52427a..ec7944b 100644 --- a/tests/core/test_logger.cpp +++ b/tests/core/test_logger.cpp @@ -266,11 +266,11 @@ TEST_CASE("Global logger functions", "[logger][global]") { init_logger(config); SECTION("Convenience functions") { - log_trace("Global trace"); - log_debug("Global debug"); - log_info("Global info"); - log_warn("Global warn"); - log_error("Global error"); + MILAI_LOG_TRACE("Global trace"); + MILAI_LOG_DEBUG("Global debug"); + MILAI_LOG_INFO("Global info"); + MILAI_LOG_WARN("Global warn"); + MILAI_LOG_ERROR("Global error"); log_critical("Global critical"); REQUIRE(true); @@ -284,7 +284,7 @@ TEST_CASE("Global logger functions", "[logger][global]") { } SECTION("Flush logger") { - log_info("Message before flush"); + MILAI_LOG_INFO("Message before flush"); flush_logger(); REQUIRE(true); @@ -434,7 +434,7 @@ TEST_CASE("Logger thread safety", "[logger][thread]") { for (int t = 0; t < num_threads; ++t) { threads.emplace_back([t]() { for (int i = 0; i < messages_per_thread; ++i) { - log_info("Thread {} message {}", t, i); + MILAI_LOG_INFO("Thread {} message {}", t, i); } }); }