空域GPU超分
=======

XEngine Kit提供空域GPU超分能力，其基于单帧输入图像，使用空间邻域信息实现超采样，开销较小同时收益可观，建议使用超分倍率为\[1.2, 1.5\]。

#### 约束与限制

*   支持的设备类型：Phone，从5.0.2(14)版本开始，新增支持Tablet、PC/2in1设备，从5.1.1(19)版本开始新增支持TV设备。
    
*   可通过以下方式查询相关扩展特性是否支持：
    
    *   对于OpenGL ES，使用[HMS\_XEG\_GetString](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/xengine-kit-xengine#hms_xeg_getstring)扩展特性查询接口进行查询。
        
    *   对于Vulkan，使用[HMS\_XEG\_EnumerateDeviceExtensionProperties](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/xengine-kit-xengine#hms_xeg_enumeratedeviceextensionproperties)扩展特性查询接口进行查询。
        
    
    如查询结果包含[XEG\_SPATIAL\_UPSCALE\_EXTENSION\_NAME](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/xengine-kit-xengine#xeg_spatial_upscale_extension_name)，则表示支持该特性，若查询结果未包含，则表示不支持该特性。
    

#### 接口说明

以下接口为OpenGL ES和Vulkan空域GPU超分设置接口，如需使用更丰富的设置和查询接口，具体API说明详见[接口文档](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/xengine-kit-xengine)。

| 接口名 | 描述 |
| :-- | :-- |
| const GLubyte \* HMS\_XEG\_GetString (GLenum name) | XEngine OpenGL ES扩展特性查询接口。 |
| GL\_APICALL void GL\_APIENTRY HMS\_XEG\_SpatialUpscaleParameter (GLenum pname, GLvoid \*param) | 设置空域GPU超分输入参数。 |
| GL\_APICALL void GL\_APIENTRY HMS\_XEG\_RenderSpatialUpscale (GLuint inputTexture) | 执行空域GPU超分渲染命令。 |
| VKAPI\_ATTR VkResult VKAPI\_CALL HMS\_XEG\_EnumerateDeviceExtensionProperties (VkPhysicalDevice physicalDevice, uint32\_t \*pPropertyCount, XEG\_ExtensionProperties \*pProperties) | XEngine Vulkan扩展特性查询接口。 |
| VKAPI\_ATTR VkResult VKAPI\_CALL HMS\_XEG\_CreateSpatialUpscale (VkDevice device, const XEG\_SpatialUpscaleCreateInfo \*pXegSpatialUpscaleCreateInfo, XEG\_SpatialUpscale \*pXegSpatialUpscale) | 创建XEG\_SpatialUpscale对象。 |
| VKAPI\_ATTR void VKAPI\_CALL HMS\_XEG\_CmdRenderSpatialUpscale (VkCommandBuffer commandBuffer, XEG\_SpatialUpscale xegSpatialUpscale, XEG\_SpatialUpscaleDescription \*pXegSpatialUpscaleDescription) | 执行空域GPU超分渲染命令。 |
| VKAPI\_ATTR void VKAPI\_CALL HMS\_XEG\_DestroySpatialUpscale (XEG\_SpatialUpscale xegSpatialUpscale) | 销毁XEG\_SpatialUpscale对象。 |

#### 业务流程

*   下面是基于GLES图形API平台集成空域GPU超分的主要业务流程
    
    ![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/93/v3/YVkCpDDOT5CQDga7Jc9gGw/zh-cn_image_0000002634009476.jpg?HW-CC-KV=V1&HW-CC-Date=20260709T132555Z&HW-CC-Expire=86400&HW-CC-Sign=861166D4FC7D89D87B6861FC818F21A082D25AE3A7CE24F9FFE0672F9ABEFE92)
    

1.  用户在进入游戏初始化场景时调用HMS\_XEG\_GetString接口查询XEngine支持的特性，当查询接口返回支持的特性列表中包含空域GPU超分时代表可以使用此特性。
2.  调用HMS\_XEG\_SpatialUpscaleParameter接口配置超分参数。
3.  当游戏运行时，游戏渲染待超分的当前帧纹理。
4.  当待超分纹理渲染完成时，调用HMS\_XEG\_RenderSpatialUpscale接口对待超分的纹理超分。
5.  当超分渲染完成时，游戏渲染剩下的纹理，如UI等。
6.  当前帧已全部渲染完成，进行送显。
7.  当游戏退出时，超分资源会自行释放。

*   下面是基于Vulkan图形API平台集成空域GPU超分的主要业务流程
    
    ![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/f3/v3/ePC_PWv7STqzo1ysvbfbaw/zh-cn_image_0000002664208625.jpg?HW-CC-KV=V1&HW-CC-Date=20260709T132555Z&HW-CC-Expire=86400&HW-CC-Sign=117D400AB672FDE41349DFF8CA0F382B9F3C239918079DE56D32C10E3022AC01)
    

1.  用户在进入游戏初始化场景时调用HMS\_XEG\_EnumerateDeviceExtensionProperties接口查询XEngine支持的特性，当查询接口返回支持的特性列表中包含空域GPU超分时代表可以使用此特性。
2.  此时调用HMS\_XEG\_CreateSpatialUpscale接口创建超分实例。
3.  当游戏运行时，游戏渲染待超分的当前帧纹理。
4.  当待超分纹理渲染完成时，调用HMS\_XEG\_CmdRenderSpatialUpscale接口对待超分的纹理超分。
5.  当超分渲染完成时，游戏渲染剩下的纹理，如UI等。
6.  当前帧已全部渲染完成，进行送显。
7.  当游戏退出时，调用HMS\_XEG\_DestroySpatialUpscale接口销毁超分实例。

#### 开发步骤

本章以OpenGL ES和Vulkan图像API集成为例，说明XEngine集成操作过程。

#### \[h2\]配置项目

编译HAP时，Native层so编译需要依赖NDK中的libxengine.so。

*   头文件引用
    
    按需引用XEngine的头文件，如使用OpenGL ES空域GPU超分。
    
    #include <cstring>
    #include <cstdlib>
    #include <xengine/xeg\_gles\_extension.h>
    #include <xengine/xeg\_gles\_spatial\_upscale.h>
    
    按需引用XEngine的头文件，如使用Vulkan空域GPU超分。
    
    #include <string>
    #include <vector>
    #include <algorithm>
    #include <xengine/xeg\_vulkan\_extension.h>
    #include <xengine/xeg\_vulkan\_spatial\_upscale.h>
    
*   编写CMakeLists.txt
    
    按需引用XEngine的CMakeLists，如使用OpenGL ES空域GPU超分功能，CMakeLists.txt部分示例代码如下，完整示例代码请参见[Demo（GPU加速引擎-GLES）](https://gitcode.com/harmonyos_samples/xengine-samplecode-gles-demo-cpp)。
    
    find\_library(
        # 设置路径变量的名称。
        xengine-lib
        # 指定希望CMake定位的NDK库的名称。
        xengine
    )
    find\_library(
        # 设置路径变量的名称。
        EGL-lib
        # 指定希望CMake定位的NDK库的名称。
        EGL
    )
    find\_library(
        # 设置路径变量的名称。
        GLES-lib
        # 指定希望CMake定位的NDK库的名称。
        GLESv3
    )
    
    target\_link\_libraries(nativerender PUBLIC
    ${EGL-lib} ${GLES-lib} ${xengine-lib})
    
    按需引用XEngine的CMakeLists，如使用Vulkan空域GPU超分功能，CMakeLists.txt部分示例代码如下，完整示例代码请参见[Demo（GPU加速引擎-Vulkan）](https://gitcode.com/harmonyos_samples/xengine-samplecode-vulkan-demo-cpp)。
    
    find\_library(
        # 设置路径变量的名称。
        xengine-lib
        # 指定希望CMake定位的NDK库的名称。
        xengine
    )
    find\_library(
        # 设置路径变量的名称。
        Vulkan-lib
        # 指定希望CMake定位的NDK库的名称。
        vulkan
    )
    
    target\_link\_libraries(nativerender PUBLIC
    ${Vulkan-lib} ${xengine-lib})
    

#### \[h2\]集成XEngine空域GPU超分（OpenGL ES）

使用EGL和OpenGL ES图形API搭建图像渲染管线并集成空域GPU超分在Native层实现，渲染结果通过[XComponent](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-basic-components-xcomponent)组件显示到屏幕。

本节阐述OpenGL ES图形API的空域GPU超分的使用，详细代码请参见[Demo（GPU加速引擎-GLES）](https://gitcode.com/harmonyos_samples/xengine-samplecode-gles-demo-cpp)。

在调用XEngine Kit能力前，需要先通过[Syscap](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/syscap#什么是systemcapabilitysyscap)查询您的目标设备是否支持SystemCapability.Graphic.XEngine系统能力。

1.  调用[HMS\_XEG\_GetString](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/xengine-kit-xengine#hms_xeg_getstring)接口，获取XEngine支持的扩展信息，只有在支持XEG\_SPATIAL\_UPSCALE\_EXTENSION\_NAME扩展时才可以使用空域GPU超分的相关接口。
    
    // 查询XEngine支持的GLES扩展信息
    const char\* extensions = (const char\*)HMS\_XEG\_GetString(XEG\_EXTENSIONS);
    // 检查是否支持空域GPU超分
    if (!strstr(extensions, XEG\_SPATIAL\_UPSCALE\_EXTENSION\_NAME)) {
        exit(1); // 异常退出
    }
    
2.  调用[HMS\_XEG\_SpatialUpscaleParameter](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/xengine-kit-xengine#hms_xeg_spatialupscaleparameter)接口，对空域GPU超分的参数赋值。
    
    // m\_sharpness为用户自定义超分锐化参数，此处以参数为0.3f为例
    float m\_sharpness = 0.3f;
    // m\_renderWidth与m\_renderHeight分别为用户自定义的渲染宽度与渲染高度，此处以800\*600分辨率为例
    uint32\_t m\_renderWidth = 800;
    uint32\_t m\_renderHeight = 600;
    HMS\_XEG\_SpatialUpscaleParameter(XEG\_SPATIAL\_UPSCALE\_SHARPNESS, &m\_sharpness);
    // upscaleScissor为超分输入图像的采样区域
    int upscaleScissor\[4\] = {0, 0, static\_cast<int>(m\_renderWidth), static\_cast<int>(m\_renderHeight)};
    HMS\_XEG\_SpatialUpscaleParameter(XEG\_SPATIAL\_UPSCALE\_SCISSOR, upscaleScissor);
    
3.  调用[HMS\_XEG\_RenderSpatialUpscale](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/xengine-kit-xengine#hms_xeg_renderspatialupscale)接口进行超分。
    
    // upscaleFBO为用户自定义创建的framebuffer
    unsigned int upscaleFBO;
    glBindFramebuffer(GL\_FRAMEBUFFER, upscaleFBO);
    // m\_upscaleWidth和m\_upscaleHeight分别为用户自定义超分宽度和超分高度，此处以超分至1200\*900分辨率为例
    uint32\_t m\_upscaleWidth = 1200;
    uint32\_t m\_upscaleHeight = 900;
    glViewport(0, 0, m\_upscaleWidth, m\_upscaleHeight);
    glScissor(0, 0, m\_upscaleWidth, m\_upscaleHeight);
    // upscaleColorBuffer为纹理附件，用户可自定义
    unsigned int upscaleColorBuffer;
    HMS\_XEG\_RenderSpatialUpscale(upscaleColorBuffer);
    
    upscaleFBO是已创建完成的framebuffer，并绑定纹理，超分接口调用后绘制到纹理上。
    

#### \[h2\]集成XEngine空域GPU超分（Vulkan）

使用Vulkan图形API搭建图像渲染管线并集成空域GPU超分在Native层实现，渲染结果通过[XComponent](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-basic-components-xcomponent)组件显示到屏幕。

本节阐述Vulkan图形API的空域GPU超分使用，详细代码请参见[Demo（GPU加速引擎-Vulkan）](https://gitcode.com/harmonyos_samples/xengine-samplecode-vulkan-demo-cpp)。

在调用XEngine Kit能力前，需要先通过[Syscap](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/syscap#什么是systemcapabilitysyscap)查询您的目标设备是否支持SystemCapability.Graphic.XEngine系统能力。

1.  调用[HMS\_XEG\_EnumerateDeviceExtensionProperties](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/xengine-kit-xengine#hms_xeg_enumeratedeviceextensionproperties)接口，获取XEngine支持的扩展信息，只有在支持XEG\_SPATIAL\_UPSCALE\_EXTENSION\_NAME扩展时才可以使用空域GPU超分的相关接口。
    
    // physicalDevice为Vulkan物理设备，用户需进行初始化
    VkPhysicalDevice physicalDevice;
    // 查询XEngine支持的Vulkan扩展列表
    std::vector<std::string> supportedExtensions;
    uint32\_t pPropertyCount;
    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 (auto ext : pProperties) {
                 supportedExtensions.push\_back(ext.extensionName);
             }
        }
    }
    // 查询是否支持空域GPU超分
    if (std::find(supportedExtensions.begin(), supportedExtensions.end(), XEG\_SPATIAL\_UPSCALE\_EXTENSION\_NAME) == supportedExtensions.end()) {
        exit(1); // 异常退出
    }
    
2.  声明实例句柄。
    
    XEG\_SpatialUpscale xegSpatialUpscale;
    
3.  调用[HMS\_XEG\_CreateSpatialUpscale](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/xengine-kit-xengine#hms_xeg_createspatialupscale)接口，创建超分实例。
    
    // 渲染宽高和超分后宽高均为用户自定义参数，此处以将800\*600分辨率超分至1200\*900分辨率为例
    uint32\_t m\_renderWidth = 800;
    uint32\_t m\_renderHeight = 600;
    uint32\_t m\_upscaleWidth = 1200;
    uint32\_t m\_upscaleHeight = 900;
    // Vulkan逻辑设备，用户需进行初始化
    VkDevice device;
    // VkRect2D为Vulkan指定的二维区域结构
    // srcRect2D为超分输入纹理区域，用户可自定义
    VkRect2D srcRect2D;
    // srcRect2D.offset.x和srcRect2D.offset.y为原点偏移量
    srcRect2D.offset.x = 0;
    srcRect2D.offset.y = 0;
    // srcRect2D.extent.width与srcRect2D.extent.height为输入纹理宽高
    srcRect2D.extent.width = m\_renderWidth;
    srcRect2D.extent.height = m\_renderHeight;
    // dstRect2D为超分输出纹理区域，用户可自定义
    VkRect2D dstRect2D;
    // dstRect2D.offset.x和dstRect2D.offset.y为原点偏移量
    dstRect2D.offset.x = 0;
    dstRect2D.offset.y = 0;
    // dstRect2D.extent.width与dstRect2D.extent.height为超分纹理宽高
    dstRect2D.extent.width = m\_upscaleWidth;
    dstRect2D.extent.height = m\_upscaleHeight;
    XEG\_SpatialUpscaleCreateInfo createInfo;
    createInfo.format = VK\_FORMAT\_R8G8B8A8\_UNORM;
    // sharpness为用户自定义超分锐化参数，此处以参数为0.3f为例
    createInfo.sharpness = 0.3f;
    createInfo.outputSize = dstRect2D.extent;
    createInfo.inputRegion = srcRect2D;
    createInfo.outputRegion = dstRect2D;
    createInfo.inputSize = srcRect2D.extent;
    HMS\_XEG\_CreateSpatialUpscale(device, &createInfo, &xegSpatialUpscale);
    
4.  调用[HMS\_XEG\_CmdRenderSpatialUpscale](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/xengine-kit-xengine#hms_xeg_cmdrenderspatialupscale)接口下发超分，每帧都需要调用。
    
    // inputImageView为用户创建的超分输入图像的VkImageView
    VkImageView inputImageView = VK\_NULL\_HANDLE;
    // outputImageView为用户创建的超分输出图像的VkImageView
    VkImageView outputImageView = VK\_NULL\_HANDLE;
    // cmdBuff为命令缓冲区，用户需进行初始化
    VkCommandBuffer cmdBuff = VK\_NULL\_HANDLE ;
    XEG\_SpatialUpscaleDescription xegDescription;
    xegDescription.inputImage = inputImageView;
    xegDescription.outputImage = outputImageView;
    HMS\_XEG\_CmdRenderSpatialUpscale(cmdBuff, xegSpatialUpscale, &xegDescription);
    
5.  调用[HMS\_XEG\_DestroySpatialUpscale](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/xengine-kit-xengine#hms_xeg_destroyspatialupscale)接口销毁实例。
    
    HMS\_XEG\_DestroySpatialUpscale(xegSpatialUpscale);