Building a Simple Engine -- Mobile Development -- Conclusion

整合所有内容

接下来我们将展示如何将上述所有组件整合到一个完整的、针对移动平台优化的 Vulkan 应用中:

cpp 复制代码
class MobileOptimizedEngine {
public:
    MobileOptimizedEngine() {
        // 初始化平台专属组件
        #ifdef __ANDROID__
            initialize_android();
        #elif defined(__APPLE__)
            initialize_ios();
        #else
            initialize_desktop();
        #endif

        // 以移动平台优化配置初始化Vulkan
        initialize_vulkan();
    }

    void run() {
        // 主应用循环
        while (!should_close()) {
            handle_platform_events();
            update();
            render();
        }

        cleanup();
    }

private:
    void initialize_vulkan() {
        // 创建实例
        vk::InstanceCreateInfo instance_info;
        // ... 设置实例参数
        instance = vk::createInstance(instance_info);

        // 选择物理设备
        physical_device = select_physical_device(instance);

        // 检测是否为TBR架构GPU
        is_tbr_gpu = is_likely_tbr_gpu(physical_device);

        // 检查扩展支持性
        auto available_extensions = physical_device.enumerateDeviceExtensionProperties();
        std::vector<const char*> supported_extensions = { VK_KHR_SWAPCHAIN_EXTENSION_NAME };

        // 若支持则添加移动平台专属扩展
        if (check_extension_support(available_extensions, VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME)) {
            supported_extensions.push_back(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME);
            use_dynamic_rendering = true;
        }

        if (check_extension_support(available_extensions, VK_KHR_DYNAMIC_RENDERING_LOCAL_READ_EXTENSION_NAME)) {
            supported_extensions.push_back(VK_KHR_DYNAMIC_RENDERING_LOCAL_READ_EXTENSION_NAME);
            use_dynamic_rendering_local_read = true;
        }

        if (check_extension_support(available_extensions, VK_EXT_SHADER_TILE_IMAGE_EXTENSION_NAME)) {
            supported_extensions.push_back(VK_EXT_SHADER_TILE_IMAGE_EXTENSION_NAME);
            use_shader_tile_image = true;
        }

        // 使用支持的扩展创建设备
        vk::DeviceCreateInfo device_info;
        device_info.setPEnabledExtensionNames(supported_extensions);
        // ... 设置其他设备参数
        device = physical_device.createDevice(device_info);

        // 初始化其他Vulkan资源
        // ...
    }

    void render() {
        // 开始帧渲染
        auto cmd_buffer = begin_frame();

        if (use_dynamic_rendering) {
            // 使用动态渲染
            vk::RenderingAttachmentInfoKHR color_attachment;
            // ... 设置附件参数

            vk::RenderingInfoKHR rendering_info;
            // ... 设置渲染参数

            cmd_buffer.beginRenderingKHR(rendering_info);

            // 记录绘制命令
            // ...

            cmd_buffer.endRenderingKHR();
        } else {
            // 使用传统渲染通道
            // ...
        }

        // 结束帧渲染
        end_frame(cmd_buffer);
    }

    // 平台专属初始化逻辑
    void initialize_android() {
        // Android平台专属配置
        // ...
    }

    void initialize_ios() {
        // iOS平台专属配置(基于MoltenVK)
        // ...
    }

    void initialize_desktop() {
        // 桌面平台专属配置
        // ...
    }

    // 辅助函数
    bool check_extension_support(const std::vector<vk::ExtensionProperties>& available, const char* extension_name) {
        for (const auto& ext : available) {
            if (strcmp(extension_name, ext.extensionName) == 0) {
                return true;
            }
        }
        return false;
    }

    bool is_likely_tbr_gpu(vk::PhysicalDevice device) {
        vk::PhysicalDeviceProperties props = device.getProperties();

        // 以下厂商的多数移动GPU采用TBR架构
        if (props.vendorID == 0x5143 ||  // 高通(Qualcomm)
            props.vendorID == 0x1010 ||  // 图芯(PowerVR)
            props.vendorID == 0x13B5 ||  // ARM Mali
            props.vendorID == 0x19E5 ||  // 华为(Huawei)
            props.vendorID == 0x106B) {  // 苹果(Apple)
            return true;
        }

        return false;
    }

    // Vulkan对象
    vk::Instance instance;
    vk::PhysicalDevice physical_device;
    vk::Device device;

    // 功能开关
    bool is_tbr_gpu = false;
    bool use_dynamic_rendering = false;
    bool use_dynamic_rendering_local_read = false;
    bool use_shader_tile_image = false;
};

上线就绪检查清单

  1. 特性检测与降级方案:启动时检测 EXT/KHR 扩展支持性,按需启用扩展,并维护经过测试的降级渲染路径;
  2. 渲染路径选择:基于简单的厂商 / 启发式检测,在运行时切换适配 TBR 的渲染路径或通用 IMR 渲染路径;
  3. 帧缓冲读取策略:优先使用瓦片本地、逐像素读取方式(输入附件或 dynamic rendering local read),避免强制触发片外内存往返的操作模式;
  4. 纹理与资源:使用 KTX2 作为资源容器;优先采用 ASTC 格式,按需降级为 ETC2/PVRTC;离线生成 mipmaps;
  5. 内存 / 附件管理:对渲染通道后无需保留结果的资源使用临时附件(transient attachments);通过子分配减少内存碎片;
  6. 功耗 / 性能调控:实现动态分辨率或画质分级机制,合理设置 FPS 上限,控制设备发热;
  7. 性能监控:添加 GPU 标记 / 时间戳、帧耗时直方图、带宽代理指标,追踪性能回退问题;
  8. 设备矩阵测试:维护小型、具有代表性的设备测试库(覆盖不同厂商 / 性能等级),定期运行基准场景测试。

验证与性能分析指南

正确性验证

  • 验证各设备的交换链参数(present mode、最小图像数量);
  • 验证布局转换与访问掩码(尤其启用 local read 时);
  • 验证渲染作用域与计算 / 传输任务间的同步逻辑。

高效性能分析

  • 使用平台工具(如 Android GPU Inspector、RenderDoc、Xcode GPU Capture)定位瓦片刷新、过度绘制、带宽热点问题;
  • 进行 A/B 测试:对比传统 render pass 与 dynamic rendering、开启 / 关闭 local read、开启 / 关闭 tile-image 的性能差异;
  • 跟踪多分钟运行时的功耗与温度变化,而非仅关注单帧表现。

后续步骤

  1. 集成能力层:向上层系统暴露特性标识(dynamic rendering、local read、tile image);
  2. 添加自动化启动检测:将设备 / 特性信息输出至日志,用于线上数据采集;
  3. 扩展基准测试场景:覆盖对 TBR 敏感、高带宽消耗的渲染路径。

拓展学习(简易引擎教程)

以下简短、聚焦的教程基于简易引擎展开,是极佳的后续学习内容:

代码示例

本章完整代码可在以下文件中找到:

Mobile Platform Integration C++ code Mobile Optimizations C++ code TBR Optimizations C++ code Mobile Extensions C++ code

相关推荐
小乌龟打怪升级4 天前
pipeline介绍
pipeline·通信连接
mxwin6 天前
unity shader中 ddx ddy是什么
unity·游戏引擎·shader
mxwin7 天前
Unity SetPassCall和DrawCall的区别是什么
unity·游戏引擎·shader
mxwin9 天前
在unity shader中,通过pass产生阴影,通过主pass的光照 接收阴影!那么问题来了,是先产生阴影吗?还是先接收阴影,执行顺序是啥呢
数码相机·unity·游戏引擎·shader
小贺儿开发10 天前
《唐朝诡事录之长安》——盛世马球
人工智能·unity·ai·shader·绘画·影视·互动
易生一世13 天前
自动化Pipeline中的Kiro CLI详解
自动化·pipeline·key·headless·kiro
mxwin17 天前
Unity Shader 半透明物体为什么不能写入深度缓冲?
unity·游戏引擎·shader
mxwin17 天前
Unity Shader 手写基于 PBR 的 URP Lit Shader 核心光照计算
unity·游戏引擎·shader
mxwin17 天前
Unity GPU Shader 性能优化指南
unity·游戏引擎·shader
mxwin19 天前
Unity Custom Interpolators与半透明阴影的原理与实战
unity·游戏引擎·shader