ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

如何快速验证 D3D12 转换管线:Madeira 的 DXIL 金丝雀着色器完整指南

如何快速验证 D3D12 转换管线:Madeira 的 DXIL 金丝雀着色器完整指南 如何快速验证 D3D12 转换管线Madeira 的 DXIL 金丝雀着色器完整指南【免费下载链接】MadeiraRun x86-64 Windows PC games on jailed iOS via FEX-Emu Wine DXMT项目地址: https://gitcode.com/GitHub_Trending/mad/MadeiraMadeira是一个让 x86-64 Windows 游戏运行在越狱 iOS 上的项目核心思路是 FEX-Emu Wine DXMT。其中最难的一环是把 Windows 的D3D12画到 Apple GPU 上——iOS 没有 D3D12每个着色器必须先把DXIL中间格式编译成 Metal 库Metal Shader Converter。这条转换管线一旦出错游戏就是黑屏。Madeira 的答案很金丝雀不直接拿游戏开刀而是先写一对极小、极刻意的 DXIL 金丝雀着色器用 26~27 项自动化检查把DXIL → 转换器 → Metal 库 → 渲染管线 → 像素读回整条链路逐层验证全部通过后才允许在其上搭建真正的 D3D12 实现。为什么需要预编译金丝雀先证明管线再谈游戏在 iOS 上跑 D3D12 游戏的完整链路是游戏 DXBC/DXIL 着色器 → Metal Shader Converter 转换 → metallib 加载 → MTLRenderPipelineState → GPU 出图 → 像素读回验证链路上任何一环失败都会静默地表现为颜色不对或启动黑屏。Madeira 的设计原则是在写任何 COM 对象代码之前先有一个门禁gate证明转换出来的着色器能正确读回我们喂进去的颜色。这就是 M1 里程碑的 msc_canary.mm 金丝雀测试它的地位相当于矿井里的金丝雀——管线坏了它先死而且死法能精确指出坏在哪一环。两个金丝雀着色器故意最小的探针金丝雀的 HLSL 源码只有几十行刻意选成能证明整条绑定路径的最小着色器单常量缓冲金丝雀canary.hlsl顶点着色器不读任何顶点缓冲用SV_VertexID生成一个全屏三角形像素着色器把b0根常量缓冲的颜色原样返回。像素值完全可预测与光栅化规则无关。布局金丝雀canary_layout.hlsl故意在根签名里放4 个 32 位根常量 1 个根 CBV两参布局——红、绿通道来自根常量蓝通道来自 CBV。这样任何一侧的偏移错误都会让像素颜色出错而不是错出一个看起来合理的颜色。两份着色器编译成的 DXIL 固件 直接放在仓库里作为测试输入绕开了顶点取数和转换器两个变量同时被测试的问题M4 里程碑的立方体再单独证明真实顶点缓冲路径。 金丝雀设计精髓错误的绑定偏移/绑定点会产出错误的颜色而不是可接受的颜色——结果二元化检查才能自动判定。26 项检查金丝雀如何逐层拆解转换管线msc_canary.mm 的检查按从加载到像素的顺序分层推进每一层独立判定层级检查内容证明什么1️⃣ 转换器加载通过dlopen/dlsym解析 24 个入口符号iOS dylib 能在进程内加载缺符号会点名报告而非 dyld 崩溃2️⃣ 根签名驱动布局显式构造根签名不复用编译器嵌入的 RTS0 块真实运行时收到的根签名来自应用参数缓冲布局必须随之正确生成3️⃣ 转换产物DXIL 转出的 metallib 在目标设备加载并建成渲染管线转换器输出对设备有效而不只是字节合法4️⃣ 像素读回两组常量状态必须精确读出(255,0,0,255)和(200,100,255,255)参数缓冲的偏移、绑定全部正确——验证而非假设5️⃣ 错误边界无效 DXIL、截断字节流、不存在的入口名全部以有界、有名字的错误失败而不是崩溃其中第 4 层最妙布局金丝雀把根常量放在字节 0..15、根 CBV 的 64 位 GPU 地址放在字节 16红/绿来自常量、蓝来自 CBV两侧任何一侧的布局错误都会显形且无歧义。缓存安全预编译产物什么时候可以复用金丝雀还顺带验证了着色器缓存的前提相同输入重编译产出字节一致的 metallib——这是把转换产物落盘复用的基础但 README 特别强调字节一致既非必要也非充分条件关键是把所有相关输入都纳入缓存键。缓存键敏感性改最低部署版本、改根签名输出必须变化或拒绝编译。GPU 族级GPU family是最深的坑同一着色器在 macOS 上 Apple9 与 Metal3 产出字节相同换到 iOS 设备上却产出不同字节——保留族级在缓存键里这个看似多余的决定在另一个平台上救了正确性。生产环境的缓存实现是 madeira_dxil_cache.h缓存键覆盖字节码、入口名、根签名、目标 OS/GPU 族/最低版本等 DXIL 分支真正读取的全部输入并额外存一个独立的 64 位校验哈希防止文件名碰撞误命中它的行为由纯 C 主机测试 dxil_cache_test.c 在无设备、无 SDK 的情况下先行验证。真机成绩单从 macOS 到 iPhone 13 Pro同一套金丝雀在不同环境全部通过结果对照如下来自 README.md环境结果首次转换耗时缓存重编译macOS M4 Max✅ 26/261.0 ms0.4 msiOS 越狱 vphone VM✅ 26/262.2 ms0.3 ms真机 iPhone 13 ProA15 GPU✅ 27/2716.8 ms0.6 ms跨目标测试更给出决定性结论iOS 上编译、macOS 上加载的 metallib 哈希与 macOS 本地编译逐字节相同iOS 设备自己转换产物 → 远程 Mac 渲染的回退方案因此不需要。金丝雀还抓到一个真实缺陷转换器不校验入口点名——用NoSuchEntryPoint编译能成功唯一线索是反射返回空函数名若不拦下故障会延后到缺少 MTLFunction才爆炸。运行时自行加边界正是金丝雀的价值。金丝雀门禁之后从 26/26 到 90/90通过门禁后项目才逐层往上盖楼每一步都保持检查数全绿M1 in-app金丝雀编译进libdxmt在 Madeira 自己的签名和沙箱里dlopen运行27/27 通过——顺带验证了dylib 能用应用的 team 签名被 dyld 接受M2独立madeira_d3d12.dllARM64EC实现 D3D12 COM ABI41/41M3真实 GPU 缓冲拷贝与读回、无屏渲染77/77运行时 DXIL 转换 M5 纹理fixture 模式彻底移除应用着色器在管线创建时当场转换90/90 通过。新手 takeaway这套方法的 3 个可复用技巧把管线对不对和游戏对不对分开验证先造一个输出完全可预测的最小探针全屏三角形 原样返回颜色失败即定位到具体环节错误必须显形探针的输出设计成错了就是错色而不是错出一个合理值才能让自动化检查二元判定在便宜的环境先跑金丝雀先在 M4 Max 跑、再上 iOS VM、最后上真机 A15——三种故障转换器本身 / 打包签名 / 启动路径被刻意分开值得各自独立的失败。相关源码与文档金丝雀着色器canary.hlsl、canary_layout.hlsl金丝雀测试msc_canary.mmDXIL 转换缓存madeira_dxil_cache.h模块里程碑与实测数据README.md转换 SDK 许可说明metal-shader-converter/README.md【免费下载链接】MadeiraRun x86-64 Windows PC games on jailed iOS via FEX-Emu Wine DXMT项目地址: https://gitcode.com/GitHub_Trending/mad/Madeira创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表