HarmonyOS GPU 超分 Vulkan 版:低分辨率变高分辨率
2026/6/8 13:44:15 网站建设 项目流程

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 及以上

搭建步骤

  1. 安装 DevEco Studio:去华为开发者官网下载安装
  2. 配置开发环境:确保网络环境正常
  3. 设备调试:使用真机进行调试

项目结构

├── entry/src/main // 代码区 │ ├── cpp │ │ ├── types │ │ │ ├── libnativerender │ │ │ └── index.d.ts // native层接口注册文件 │ │ │── napi_init.cpp // native api层接口的具体实现函数 │ │ │── CMakeLists.txt // native层编译配置 │ │ │── 3rdParty // 三方件 │ │ │── common // 通用接口 │ │ │── file // 文件管理 │ │ │── libs // 三方动态库 │ │ │── manager // native&arkts交互 │ │ │── render // 渲染 │ │ │── vulkanbase // vulkan基础能力封装 │ ├── ets │ │ ├── entryability │ │ │ └── EntryAbility.ts // 程序入口类 │ │ ├── pages │ │ │ └── index.ets // 主界面展示类 │ ├── resources // 资源文件目录 │ │ ├── base │ │ │ ├── media │ │ │ └── icon.png // 图片资源 │ │ ├── rawfile │ │ │ ├── Sponza │ │ │ └── sponza.obj // 模型资源

第一步:引入头文件

#include<string>#include<vector>#include<algorithm>#include<xengine/xeg_vulkan_extension.h>#include<xengine/xeg_vulkan_spatial_upscale.h>

和 OpenGL ES 版本类似,但用的是 Vulkan 版本的头文件。

第二步:配置 CMakeLists.txt

find_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})

链接了xengineEGLvulkan三个库。

第三步:查询设备是否支持超分

VkPhysicalDevice physicalDevice;std::vector<std::string>supportedExtensions;uint32_tpPropertyCount;HMS_XEG_EnumerateDeviceExtensionProperties(physicalDevice,&pPropertyCount,nullptr);if(pPropertyCount>0){std::vector<XEG_ExtensionProperties>pProperties(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_renderWidth=800;uint32_tm_renderHeight=600;uint32_tm_upscaleWidth=1200;uint32_tm_upscaleHeight=900;VkDevice device;

定义渲染分辨率(800x600)和超分后的目标分辨率(1200x900)。

VkRect2D srcRect2D;srcRect2D.offset.x=0;srcRect2D.offset.y=0;srcRect2D.extent.width=m_renderWidth;srcRect2D.extent.height=m_renderHeight;

设置输入区域。srcRect2D定义了从哪里读取原始图像:

  • offset:起始偏移,从 (0, 0) 开始
  • extent:大小,等于原始渲染分辨率
VkRect2D dstRect2D;dstRect2D.offset.x=0;dstRect2D.offset.y=0;dstRect2D.extent.width=m_upscaleWidth;dstRect2D.extent.height=m_upscaleHeight;

设置输出区域。dstRect2D定义了超分结果写到哪里:

  • offset:起始偏移,从 (0, 0) 开始
  • extent:大小,等于超分后的目标分辨率
XEG_SpatialUpscaleCreateInfo createInfo;createInfo.format=VK_FORMAT_R8G8B8A8_UNORM;createInfo.sharpness=0.3f;createInfo.outputSize=dstRect2D.extent;createInfo.inputRegion=srcRect2D;createInfo.outputRegion=dstRect2D;createInfo.inputSize=srcRect2D.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 inputImageView=VK_NULL_HANDLE;VkImageView outputImageView;VkCommandBuffer cmdBuff=VK_NULL_HANDLE;

定义输入和输出的图像视图,以及命令缓冲区:

  • inputImageView:原始低分辨率图像
  • outputImageView:超分后的高分辨率图像
  • cmdBuff:Vulkan 命令缓冲区
XEG_SpatialUpscaleDescription xegDescription;xegDescription.inputImage=inputImageView;xegDescription.outputImage=outputImageView;HMS_XEG_CmdRenderSpatialUpscale(cmdBuff,xegSpatialUpscale,&xegDescription);

设置输入输出图像,然后调用HMS_XEG_CmdRenderSpatialUpscale执行超分。这个命令会被记录到命令缓冲区里,等 GPU 执行时才会真正运行。

第六步:销毁实例

HMS_XEG_DestroySpatialUpscale(xegSpatialUpscale);

不需要超分功能时,销毁实例,释放内存资源。

OpenGL ES 版和 Vulkan 版的区别

你可能会问:既然功能一样,为什么要有两个版本?主要区别在于:

  1. 性能:Vulkan 通常性能更好,因为它的底层控制更精细
  2. 复杂度:Vulkan 的代码更复杂,需要手动管理很多东西
  3. 兼容性:OpenGL ES 兼容性更好,几乎所有设备都支持

选择哪个版本取决于你的需求:

  • 如果追求性能,选 Vulkan
  • 如果追求开发效率,选 OpenGL ES

Vulkan 版 GPU 超分的整体工作流程如下:

查询设备是否支持超分扩展

创建超分实例

配置锐化参数和输入输出区域

获取输入输出 ImageView

设置超分描述结构体

调用 CmdRenderSpatialUpscale

命令记录到 CommandBuffer

GPU 执行超分

输出高分辨率图像

销毁超分实例

OpenGL ES 版与 Vulkan 版的选择决策:

OpenGL ES

Vulkan

需要GPU超分功能

应用使用哪个图形API?

使用 GLES 版超分

使用 Vulkan 版超分

直接调用 RenderSpatialUpscale

创建实例并记录到 CommandBuffer

适合开发效率优先的场景

适合性能优先的场景

适用场景

GPU 超分特别适合以下场景:

  • 游戏渲染:先用低分辨率渲染(性能好),再超分到高分辨率(画质好)
  • 视频播放:把低分辨率视频超分到高分辨率显示
  • 图片查看:放大图片时保持清晰度

注意事项

  1. 设备支持:不是所有设备都支持 GPU 超分,一定要先查询扩展
  2. 锐化参数sharpness要根据实际效果来调整
  3. 分辨率比例:超分的倍率不宜过大,一般 1.5 到 2 倍比较合适
  4. 性能开销:超分本身有性能开销,要权衡画质提升和性能损失

总结

Vulkan 版本的 GPU 超分和 OpenGL ES 版本功能相同,核心流程:

  1. 查询设备是否支持超分
  2. 创建超分实例,配置参数(锐化度、输入输出区域)
  3. 调用HMS_XEG_CmdRenderSpatialUpscale执行超分
  4. 销毁实例

如果你的应用已经在用 Vulkan,那直接用 Vulkan 版本的超分会更方便。如果用的是 OpenGL ES,就用 OpenGL ES 版本。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询