HarmonyOS GPU 超分 Vulkan 版低分辨率变高分辨率什么是 GPU 超分上一篇我们介绍了用 OpenGL ES 实现 GPU 超分这篇来看看用 Vulkan 怎么做。功能是一样的把低分辨率图像重建成高分辨率图像但 Vulkan 版本通常性能更好。简单回顾一下GPU 超分不是简单地拉伸像素而是通过算法智能补充细节。就像一个画家看到模糊的小照片然后凭技巧画出清晰的大画。环境搭建硬件要求设备类型请参考 XEngine 开发指南的硬件要求软件要求DevEco Studio 版本DevEco Studio 6.0.0 Release 及以上HarmonyOS SDK 版本HarmonyOS 6.0.0 Release SDK 及以上搭建步骤安装 DevEco Studio去华为开发者官网下载安装配置开发环境确保网络环境正常设备调试使用真机进行调试项目结构├── entry/src/main // 代码区 │ ├── cpp │ │ ├── types │ │ │ ├── libnativerender │ │ │ └── index.d.ts // native层接口注册文件 │ │ │── napi_init.cpp // native api层接口的具体实现函数 │ │ │── CMakeLists.txt // native层编译配置 │ │ │── 3rdParty // 三方件 │ │ │── common // 通用接口 │ │ │── file // 文件管理 │ │ │── libs // 三方动态库 │ │ │── manager // nativearkts交互 │ │ │── render // 渲染 │ │ │── vulkanbase // vulkan基础能力封装 │ ├── ets │ │ ├── entryability │ │ │ └── EntryAbility.ts // 程序入口类 │ │ ├── pages │ │ │ └── index.ets // 主界面展示类 │ ├── resources // 资源文件目录 │ │ ├── base │ │ │ ├── media │ │ │ └── icon.png // 图片资源 │ │ ├── rawfile │ │ │ ├── Sponza │ │ │ └── sponza.obj // 模型资源第一步引入头文件#includestring#includevector#includealgorithm#includexengine/xeg_vulkan_extension.h#includexengine/xeg_vulkan_spatial_upscale.h和 OpenGL ES 版本类似但用的是 Vulkan 版本的头文件。第二步配置 CMakeLists.txtfind_library( xengine-lib xengine ) find_library( EGL-lib EGL ) find_library( Vulkan-lib vulkan ) target_link_libraries(nativerender PUBLIC ${EGL-lib} ${Vulkan-lib} ${xengine-lib})链接了xengine、EGL和vulkan三个库。第三步查询设备是否支持超分VkPhysicalDevice physicalDevice;std::vectorstd::stringsupportedExtensions;uint32_tpPropertyCount;HMS_XEG_EnumerateDeviceExtensionProperties(physicalDevice,pPropertyCount,nullptr);if(pPropertyCount0){std::vectorXEG_ExtensionPropertiespProperties(pPropertyCount);if(HMS_XEG_EnumerateDeviceExtensionProperties(physicalDevice,pPropertyCount,pProperties.front())VK_SUCCESS){for(autoext:pProperties){supportedExtensions.push_back(ext.extensionName);}}}if(std::find(supportedExtensions.begin(),supportedExtensions.end(),XEG_SPATIAL_UPSCALE_EXTENSION_NAME)supportedExtensions.end()){exit(1);// return error}和 OpenGL ES 版本一样先查询设备支持的扩展然后检查是否支持空域超分。Vulkan 的查询方式是先问数量再取数据的两步式调用。第四步创建超分实例XEG_SpatialUpscale xegSpatialUpscale;声明一个超分实例句柄就像一个遥控器。uint32_tm_renderWidth800;uint32_tm_renderHeight600;uint32_tm_upscaleWidth1200;uint32_tm_upscaleHeight900;VkDevice device;定义渲染分辨率800x600和超分后的目标分辨率1200x900。VkRect2D srcRect2D;srcRect2D.offset.x0;srcRect2D.offset.y0;srcRect2D.extent.widthm_renderWidth;srcRect2D.extent.heightm_renderHeight;设置输入区域。srcRect2D定义了从哪里读取原始图像offset起始偏移从 (0, 0) 开始extent大小等于原始渲染分辨率VkRect2D dstRect2D;dstRect2D.offset.x0;dstRect2D.offset.y0;dstRect2D.extent.widthm_upscaleWidth;dstRect2D.extent.heightm_upscaleHeight;设置输出区域。dstRect2D定义了超分结果写到哪里offset起始偏移从 (0, 0) 开始extent大小等于超分后的目标分辨率XEG_SpatialUpscaleCreateInfo createInfo;createInfo.formatVK_FORMAT_R8G8B8A8_UNORM;createInfo.sharpness0.3f;createInfo.outputSizedstRect2D.extent;createInfo.inputRegionsrcRect2D;createInfo.outputRegiondstRect2D;createInfo.inputSizesrcRect2D.extent;配置创建参数format图像格式VK_FORMAT_R8G8B8A8_UNORM表示 RGBA 四通道每个通道 8 位sharpness锐化参数0.3 是一个平衡值outputSize输出尺寸inputRegion输入区域outputRegion输出区域inputSize输入尺寸HMS_XEG_CreateSpatialUpscale(device,createInfo,xegSpatialUpscale);调用HMS_XEG_CreateSpatialUpscale创建超分实例。第五步执行超分VkImageView inputImageViewVK_NULL_HANDLE;VkImageView outputImageView;VkCommandBuffer cmdBuffVK_NULL_HANDLE;定义输入和输出的图像视图以及命令缓冲区inputImageView原始低分辨率图像outputImageView超分后的高分辨率图像cmdBuffVulkan 命令缓冲区XEG_SpatialUpscaleDescription xegDescription;xegDescription.inputImageinputImageView;xegDescription.outputImageoutputImageView;HMS_XEG_CmdRenderSpatialUpscale(cmdBuff,xegSpatialUpscale,xegDescription);设置输入输出图像然后调用HMS_XEG_CmdRenderSpatialUpscale执行超分。这个命令会被记录到命令缓冲区里等 GPU 执行时才会真正运行。第六步销毁实例HMS_XEG_DestroySpatialUpscale(xegSpatialUpscale);不需要超分功能时销毁实例释放内存资源。OpenGL ES 版和 Vulkan 版的区别你可能会问既然功能一样为什么要有两个版本主要区别在于性能Vulkan 通常性能更好因为它的底层控制更精细复杂度Vulkan 的代码更复杂需要手动管理很多东西兼容性OpenGL ES 兼容性更好几乎所有设备都支持选择哪个版本取决于你的需求如果追求性能选 Vulkan如果追求开发效率选 OpenGL ESVulkan 版 GPU 超分的整体工作流程如下查询设备是否支持超分扩展创建超分实例配置锐化参数和输入输出区域获取输入输出 ImageView设置超分描述结构体调用 CmdRenderSpatialUpscale命令记录到 CommandBufferGPU 执行超分输出高分辨率图像销毁超分实例OpenGL ES 版与 Vulkan 版的选择决策OpenGL ESVulkan需要GPU超分功能应用使用哪个图形API?使用 GLES 版超分使用 Vulkan 版超分直接调用 RenderSpatialUpscale创建实例并记录到 CommandBuffer适合开发效率优先的场景适合性能优先的场景适用场景GPU 超分特别适合以下场景游戏渲染先用低分辨率渲染性能好再超分到高分辨率画质好视频播放把低分辨率视频超分到高分辨率显示图片查看放大图片时保持清晰度注意事项设备支持不是所有设备都支持 GPU 超分一定要先查询扩展锐化参数sharpness要根据实际效果来调整分辨率比例超分的倍率不宜过大一般 1.5 到 2 倍比较合适性能开销超分本身有性能开销要权衡画质提升和性能损失总结Vulkan 版本的 GPU 超分和 OpenGL ES 版本功能相同核心流程查询设备是否支持超分创建超分实例配置参数锐化度、输入输出区域调用HMS_XEG_CmdRenderSpatialUpscale执行超分销毁实例如果你的应用已经在用 Vulkan那直接用 Vulkan 版本的超分会更方便。如果用的是 OpenGL ES就用 OpenGL ES 版本。