WWDC Quick Look 💓 By SwiftGGTeam
Port advanced games to Apple platforms

Port advanced games to Apple platforms

观看原视频

Highlight

Game Porting Toolkit 2 新增 AVX 与光线追踪评估支持,Metal Shader Converter 可携带 HLSL 调试信息,一次编译 Shader 即可部署到 macOS 和 iOS。


核心内容

把一个 Windows AAA 游戏移植到 Mac,过去意味着重写 Shader、重新对接图形 API、逐平台调试——周期动辄数月。去年 Apple 推出第一代 Game Porting Toolkit(GPTK),提供了评估环境让开发者不改代码就能看游戏在 Apple Silicon 上的表现,但支持的技术范围有限:没有 AVX 指令集,没有光线追踪,兼容性和性能也与最终移植版有差距。Ubisoft 用 GPTK 把《Assassin’s Creed Mirage》的 Shader 搬到了 Metal,省下了几个月,但整个流程里仍有大量手工活。

GPTK 2 针对这些痛点做了三件事。第一,评估环境补齐了关键能力:支持 AVX 指令集、光线追踪,图形和计算的兼容性提高,性能更接近移植后的真实水平——你在评估阶段看到的帧率,就能较准确地预判最终体验。第二,Shader 工具链打通了调试闭环:Metal Shader Converter 现在会携带 HLSL 源码的调试信息到 Metal 库中,Xcode 的 Shader Debugger 和 Shader Profiler 可以直接在原始 HLSL 代码上断点、查看变量、定位性能热点,不管你是在跑评估环境的 Windows 二进制还是在调 Metal 版本。第三,多设备部署从两次编译变成一次:Unified Metal Shaders 让你编译 Shader 到 MetalIR 一次,macOS 和 iOS 通用;Metal Device 初始化 API 统一;Device Certification API 让你按设备性能等级动态调节画质。

整个移植流程被组织为三个阶段:评估(不改代码跑 Windows 二进制)、移植(用示例代码项目搭建 Xcode 工程)、调试优化(Metal 工具全流程可用)。GPTK 2 还附带了一个完整的 2D 游戏 Xcode 项目,涵盖图形、Shader、音频、手柄输入、Cloud Saves 等子系统,可以直接 build & run,也可以拆出需要的模块。


详细内容

评估环境:先跑起来再动手

评估环境是 GPTK 的入口。你把 Windows 游戏的可执行文件放进评估环境,它在 Apple Silicon 上通过兼容层运行,给出基线性能数据和 Shader 转换结果。今年的升级:

  • AVX 指令集支持:此前使用 AVX 的 Windows 游戏无法评估,现在可以了(02:37)。
  • 光线追踪支持:评估环境现在可以运行使用 DXR 的游戏(02:44)。
  • 性能提升:图形和计算兼容性改善,帧率更接近最终移植版(02:51)。

社区已经基于 GPTK 做了 Whisky、Homebrew 等封装工具,CrossOver 也集成了评估环境。

项目配置:一个工程覆盖 macOS 和 iOS

Xcode 项目可以同时 target macOS 和 iOS。大部分游戏代码是共享的,用 “Always Used” 过滤器即可。只有应用生命周期、平台特定 API 调用需要做区分,可以用 target conditional 或 SDK-based filter(06:22)。

今年的关键统一 API:

  • Unified Metal Shaders:编译一次,部署到 macOS 和 iOS(07:56)。
  • Metal Device 初始化统一:同一个创建 API 用于两个平台(08:03)。
  • Device Certification API:查询设备性能等级,动态调节配置(08:09)。
  • Game Mode 登陆 iOS:在 Info.plist 中添加 GCSupportsGameMode = true 即可开启,iOS 会降低后台活动并减少蓝牙延迟(08:17)。

Metal Shader Converter:HLSL 到 Metal 的桥梁

Metal Shader Converter 支持所有 Shader 阶段,包括光线追踪和 Mesh Shader,也覆盖传统的 Geometry 和 Tessellation Shader(09:34)。它还帮你移植 resource layout 到 Metal,附带一个 header-only runtime 库用于绑定资源和执行常见任务。

今年的两个重要更新:

  • Globally-coherent texture access:支持开发需要跨线程组可见的纹理操作的高级算法(10:29)。
  • 调试信息传递:在 DXC 编译时加 -Zi -Qembed_debug 参数,Converter 会把调试信息传递到 Metal 库,Xcode 工具可以直接调试原始 HLSL 代码(22:34)。

可以通过命令行工具或动态库调用 Converter,Windows 和 macOS 均可用。

Residency Sets:简化 GPU 资源驻留管理

Apple 平台采用统一内存模型,GPU 可以访问大量内存,但你需要显式告诉 Metal 哪些资源需要驻留。以前要逐个追踪,今年新增 Residency Sets,可以批量管理(11:58)。

// Build a residency set.

// Create a new residency set.
MTL::ResidencySet* residencySet;
residencySet = device->newResidencySet(residencySetDescriptor, &error);

// Add to main command queue.
commandQueue->addResidencySet(residencySet);

// Add allocations and commit changes.
residencySet->addAllocation(texture);
residencySet->addAllocation(buffer);
residencySet->addAllocation(heap);
residencySet->commit();

// Use residency sets.

// Allocate and encode a command buffer.
MTL::CommandBuffer* commandBuffer = commandQueue->commandBuffer();

// ...

// The command queue marks residency for the set for this command buffer.
commandBuffer->commit();

关键点:

  • newResidencySet 从 Metal Device 创建驻留集,传入 descriptor 和错误指针(12:51)。
  • addResidencySet 把驻留集绑定到 command queue,之后该 queue 上的所有 command buffer 都会自动标记驻留。
  • addAllocation 可以添加 texture、buffer 甚至整个 heap,一次 commit 生效。
  • 设置只需做一次(创建或移除资源时),绘制时正常编码 command buffer,commit 时自动继承驻留集。

这对光线追踪特别有用——把场景的所有资源装进一个驻留集,一次标记全部驻留。

MetalFX:Temporal Scaler 新增 Reactive Mask

MetalFX 通过低分辨率渲染 + 超采样来提升帧率。Temporal Scaler 使用时间累积信息,今年新增 reactive mask 可选特性(15:00)。

// Upscale image with MetalFX.

mfxTemporalScaler->setColorTexture(currentFrameColor);
mfxTemporalScaler->setDepthTexture(currentFrameDepth);
mfxTemporalScaler->setMotionTexture(currentFrameMotion);
mfxTemporalScaler->setOutputTexture(currentFrameUpscaledColor);

mfxTemporalScaler->setJitterOffsetX(currentFrameJitter.x);
mfxTemporalScaler->setJitterOffsetY(currentFrameJitter.y);

mfxTemporalScaler->setReactiveMaskTexture(currentFrameReactiveMask);

mfxTemporalScaler->encodeToCommandBuffer(commandBuffer);

关键点:

  • 设置 color、depth、motion 三张输入纹理和一张输出纹理(14:46)。
  • Jitter offset 告诉 scaler 当前帧的亚像素偏移,用于时间累积对齐。
  • setReactiveMaskTexture 是今年新增的可选接口,用于标记使用 alpha blending 的快速移动物体——这些物体的运动信息不准确,reactive mask 可以提高此类场景的超采样质量。
  • 最后 encodeToCommandBuffer 把超采样 pass 编码到命令缓冲区。

Cloud Saves:跨设备存档同步

GPTK 2 示例项目提供了 CloudSaveManager 类,封装了 CloudKit 存档同步逻辑(19:33)。

// Use the cloud save manager.

CloudSaveManager* cloudSaveManager =
    [[CloudSaveManager alloc] initWithCloudIdentifier:@"iCloud.com.mycompany.mygame"
                              saveDirectoryURL:[NSURL fileURLWithPath:@"/path/to/saves"]];

[cloudSaveManager syncWithCompletionHandler:^(BOOL conflictDetected, NSError *error) {
    // Handle conflicts or errors, for example, by presenting a choice.
}];

// Access and write saves
[cloudSaveManager uploadWithCompletionHandler:^(BOOL conflictDetected, NSError *error) {
    // Handle errors and conflicts or delay until the next sync.
}];

关键点:

  • initWithCloudIdentifier 传入 iCloud 容器标识和本地存档目录 URL(19:53)。
  • syncWithCompletionHandler 在游戏启动时调用,拉取云端存档并与本地合并;completion handler 处理冲突。
  • uploadWithCompletionHandler 在每次写入存档文件后调用,把变更推到 iCloud。

Metal 工具:全流程 HLSL 调试

Metal 工具今年最大的变化是支持调试 HLSL 源码。准备步骤很简单:在 DXC 编译 HLSL 时加 -Zi -Qembed_debug,Converter 自动传递调试信息到 Metal 库(22:34)。

三个关键工具:

  1. Runtime Validation:API Validation 检查 Metal API 调用的合法性(极轻量,全程开启);Shader Validation 检查 Shader 中的未定义行为,今年新增纹理类型不匹配检测——这是绑定纹理到转换后 Shader 时的常见错误(22:58)。今年还支持按 pipeline 选择性开关 Shader Validation,减少无关噪音。
  2. Shader Debugger:显示每行代码的变量值,左侧 Debug Navigator 展示完整执行历史,右侧显示变量预览,点击可查看邻近像素的值和执行掩码(24:52)。
  3. Shader Profiler:Shader Cost Graph 展示最耗时的函数调用,源码行级标注性能统计;Performance Heat Map 可视化屏幕上哪些像素最耗时,选中像素后可查看 SIMD 组的执行历史和调用栈(25:48)。

所有工具在评估环境跑 Windows 二进制和调试 Metal 版本时都可用。


核心启发

  1. 用 Residency Sets 管理光线追踪场景资源

    • 为什么值得做:逐个追踪纹理和缓冲区的驻留状态容易遗漏、增加 CPU 开销,Residency Sets 一次 commit 全部搞定,代码更简洁,CPU overhead 更低。
    • 怎么开始:把场景的所有 texture、buffer、heap 加入同一个 ResidencySet,绑定到 command queue,之后 commit command buffer 时自动继承驻留。
  2. MetalFX Temporal Scaler + Reactive Mask 提升帧率

    • 为什么值得做:低分辨率渲染加超采样是提升帧率的标准方案,reactive mask 解决了 alpha blending 场景下运动信息不准确导致的画面模糊问题。
    • 怎么开始:在渲染管线中插入 MetalFX temporal scaler pass,对使用 alpha blending 的快速物体生成 reactive mask 纹理,通过 setReactiveMaskTexture 传入。
  3. CloudKit 实现跨设备存档同步

    • 为什么值得做:玩家在家用 Mac,通勤用 iPhone,在咖啡厅用 iPad——存档不互通会直接打断体验。CloudKit 是 Apple 生态内最直接的跨设备同步方案。
    • 怎么开始:参考示例项目的 CloudSaveManager 类,游戏启动时 sync 拉取云端存档,每次写入后 upload 推送变更,completion handler 中处理冲突。
  4. DXC 加 -Zi -Qembed_debug 让 Metal 工具直接调试 HLSL

    • 为什么值得做:移植过程中 Shader bug 最难定位,能在 Xcode 里直接看原始 HLSL 代码的变量值和执行路径,省去在两个工具链之间反复切换的麻烦。
    • 怎么开始:修改 HLSL 编译脚本,给 DXC 加上 -Zi -Qembed_debug 参数,重新编译 Shader 后即可在 Xcode 的 Shader Debugger 和 Profiler 中看到 HLSL 源码。

关联 Session

评论

GitHub Issues · utterances