跳过正文
  1. 项目/
  2. Bocchi House 移植平台/

Bocchi House:Vulkan RAII 封装(12 个类)

·223 字·2 分钟·
FunBocchi
作者
FunBocchi
游戏引擎、图形编程爱好者。正在把 MonoGame 3.8.x 逐行移植为 C++20 并跑在鸿蒙上;也在做 Bocchi House 游戏移植平台与各种经典游戏的 HarmonyOS 移植。
目录
Bocchi House 移植平台 - 这篇文章属于一个选集。
§ : 本文

为什么需要 RAII 封装
#

Vulkan 的对象模型对 C++ 使用者很不友好:

  • 对象数量多:Instance、Device、Swapchain、CommandPool、Pipeline……十几个类型,每个都要手动 vkCreate* / vkDestroy*
  • 销毁顺序敏感:Swapchain 要在 Device 之前销毁,CommandBuffer 要在 CommandPool 之前销毁,顺序错了就校验层报错
  • 出错路径难清理:中途失败时,前面创建的对象必须全部释放,手写 goto cleanup 是常态

RAII 封装的思路很简单:每个 Vulkan 对象对应一个 C++ 类,构造函数创建、析构函数销毁。对象天然拥有资源,离开作用域自动释放,顺序问题交给成员声明顺序解决。

12 个 RAII 类
#

VulkanInstance    → VkInstance           (API 1.3 降级支持)
VulkanSurface     → VkSurfaceKHR         (vkCreateSurfaceOHOS,鸿蒙专属)
VulkanDevice      → VkDevice + Queue     (物理设备选择 + 逻辑设备 + 队列)
VulkanSwapchain   → VkSwapchainKHR + ImageViews
VulkanCommand     → CommandPool + CommandBuffer[]
VulkanSync        → Semaphore[] + Fence[]
VulkanRenderPass  → RenderPass + Framebuffer[]
VulkanShader      → ShaderModule + Pipeline
VulkanPipeline    → GraphicsPipeline + Layout
VulkanBuffer      → Buffer + DeviceMemory
VulkanImage       → Image + DeviceMemory + View + Sampler
VulkanDescriptor  → DescriptorPool + SetLayout + Sets

配套还有两个工具类:

  • VulkanCheckVK_CHECK 宏 + 错误码转字符串(踩坑时能把 VK_ERROR_OUT_OF_DATE_KHR 之类的错误一眼认出来)
  • VulkanDebug:Debug Messenger 回调(校验层信息带函数名和消息类型)

初始化序列(已验证)
#

鸿蒙端完整初始化序列如下,每行对应一个 RAII 类:

VulkanInstance::Create()     → VkInstance (API 1.3 降级支持)
VulkanSurface::Create()      → VkSurfaceKHR (vkCreateSurfaceOHOS)
VulkanDevice::Create()       → VkDevice + Queue (GPU: Maleoon 916)
VulkanSwapchain::Create()    → VkSwapchainKHR + ImageViews
VulkanCommand::Create()      → CommandPool + CommandBuffer[]
VulkanSync::Create()         → Semaphore[] + Fence[]
VulkanRenderPass::Create()   → RenderPass + Framebuffer[]

设备选择逻辑里有个小亮点:PickPhysicalDevice 按独显评分择优FindQueueFamilies + CheckDeviceExtensionSupport + QuerySwapchainSupport 组成了完整的设备检测链。

鸿蒙专属的部分
#

Vulkan 是跨平台的,但鸿蒙有它自己的"方言":

  • vkCreateSurfaceOHOS:从 OHNativeWindow 创建 VkSurfaceKHR,这是鸿蒙独有的扩展
  • API 版本降级支持:Instance 创建时优先 API 1.3,不满足就降级
  • XComponent + SurfaceHolder:渲染表面来自 ArkTS 侧的 XComponent,通过 SurfaceHolderNDK 拿到 OHNativeWindow

踩坑记录
#

  1. 销毁顺序:最初把资源全部裸指针管理,Swapchain 重建时偶发校验层报错。改成 RAII 后,按成员声明顺序析构,问题消失。
  2. Debug Messenger:忘了注册 VulkanDebug 时,VK_ERROR_OUT_OF_DATE_KHR 这类错误只有错误码没有上下文,排查全靠猜。注册后信息量大增。
  3. float16 支持CreateLogicalDeviceAndQueue 里显式启用了 float16Int8 / shaderInt16 / samplerAnisotropy 三个特性,某些驱动默认不启用,不声明就白屏。

下一步
#

RAII 层稳定后,接下来是把 BHRenderSetupVKContext(window) 完整接线:创建 Instance → Surface → Device 后,启动渲染线程,让 BHGraphicsCore::InitRender 真正跑起来。

Bocchi House 移植平台 - 这篇文章属于一个选集。
§ : 本文

相关文章