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)。
三个关键工具:
- Runtime Validation:API Validation 检查 Metal API 调用的合法性(极轻量,全程开启);Shader Validation 检查 Shader 中的未定义行为,今年新增纹理类型不匹配检测——这是绑定纹理到转换后 Shader 时的常见错误(22:58)。今年还支持按 pipeline 选择性开关 Shader Validation,减少无关噪音。
- Shader Debugger:显示每行代码的变量值,左侧 Debug Navigator 展示完整执行历史,右侧显示变量预览,点击可查看邻近像素的值和执行掩码(24:52)。
- Shader Profiler:Shader Cost Graph 展示最耗时的函数调用,源码行级标注性能统计;Performance Heat Map 可视化屏幕上哪些像素最耗时,选中像素后可查看 SIMD 组的执行历史和调用栈(25:48)。
所有工具在评估环境跑 Windows 二进制和调试 Metal 版本时都可用。
核心启发
-
用 Residency Sets 管理光线追踪场景资源
- 为什么值得做:逐个追踪纹理和缓冲区的驻留状态容易遗漏、增加 CPU 开销,Residency Sets 一次 commit 全部搞定,代码更简洁,CPU overhead 更低。
- 怎么开始:把场景的所有 texture、buffer、heap 加入同一个 ResidencySet,绑定到 command queue,之后 commit command buffer 时自动继承驻留。
-
MetalFX Temporal Scaler + Reactive Mask 提升帧率
- 为什么值得做:低分辨率渲染加超采样是提升帧率的标准方案,reactive mask 解决了 alpha blending 场景下运动信息不准确导致的画面模糊问题。
- 怎么开始:在渲染管线中插入 MetalFX temporal scaler pass,对使用 alpha blending 的快速物体生成 reactive mask 纹理,通过
setReactiveMaskTexture传入。
-
CloudKit 实现跨设备存档同步
- 为什么值得做:玩家在家用 Mac,通勤用 iPhone,在咖啡厅用 iPad——存档不互通会直接打断体验。CloudKit 是 Apple 生态内最直接的跨设备同步方案。
- 怎么开始:参考示例项目的 CloudSaveManager 类,游戏启动时 sync 拉取云端存档,每次写入后 upload 推送变更,completion handler 中处理冲突。
-
DXC 加
-Zi -Qembed_debug让 Metal 工具直接调试 HLSL- 为什么值得做:移植过程中 Shader bug 最难定位,能在 Xcode 里直接看原始 HLSL 代码的变量值和执行路径,省去在两个工具链之间反复切换的麻烦。
- 怎么开始:修改 HLSL 编译脚本,给 DXC 加上
-Zi -Qembed_debug参数,重新编译 Shader 后即可在 Xcode 的 Shader Debugger 和 Profiler 中看到 HLSL 源码。
关联 Session
- Design advanced games for Apple platforms — 如何让移植后的游戏在 Mac、iPad、iPhone 上符合 Apple 平台的设计习惯
- Bring your iOS or iPadOS game to visionOS — 把 iOS/iPadOS 游戏进一步带到 visionOS 的方法
- Render Metal with passthrough in visionOS — 在 visionOS 中结合 Metal 渲染与透视的最佳实践
- Explore game input in visionOS — visionOS 上游戏输入的设计与实现
评论
GitHub Issues · utterances