b-bridge - 进程外 Direct3D 9 渲染

b-bridge - 进程外 Direct3D 9 渲染

研究版发布。将GTA IV的整个Direct3D 9设备移入一个单独的64位进程(NVIDIA bridge-remix的一个调优分支,运行纯DXVK),在帧时间保持均衡的情况下,将约880 MB的地址空间返回给32位游戏。在一个RTX 2070系统上测量;安装前请阅读“限制”部分。

b-bridge:为《GTA IV:完全版》实现进程外 Direct3D 9 渲染

一项研究性发布。NVIDIA bridge-remix 的分支。源代码、问题与发布地址:github.com/gutbash/b-bridge

摘要

《GTA IV》是一个 32 位进程。图形驱动程序代表游戏分配的每一个资源(纹理、阴影贴图、渲染目标、暂存缓冲区)都与游戏自身的数据映射到同一个 4 GB 地址空间中,而一个重度修改的安装会在耗尽内存或显存之前很久就耗尽该空间。b-bridge 将整个 Direct3D 9 设备移入一个独立的 64 位进程。游戏保留一个精简的 32 位 d3d9.dll,通过共享内存通道将每次调用转发给一个 64 位服务器,该服务器通过 DXVK 在 Vulkan 上渲染。在测试系统上,这为游戏返回了约 880 MB 的地址空间,并将帧时间维持在进程内 DXVK 的水平,使得一个 5 GB 的纹理包组合得以运行,而此前相同的安装会在几分钟内崩溃。

问题

地址空间上限,而非内存,是《GTA IV》模组化的实际瓶颈。大地址感知标志、流式传输预算调整、-nomemrestrict 系列以及 DXVK 中的纹理内存上限可以减轻压力,但无法改变驱动程序分配和游戏分配共享一个 32 位空间的事实。在此工作之前的参考安装上测得:在视野距离为 100 时,最大连续空闲区域低至 5 MB,并且在已提交内存达 2.8 至 3.0 GB 时出现流式分配器崩溃带。

方法

NVIDIA RTX Remix 的 IPC 层已经实现了跨进程的 D3D9 数据编组;其目的是为路径追踪器提供数据。b-bridge 保留了传输层并移除了渲染器:服务器加载未修改的 DXVK 3.0.2 而非 Remix 运行时,客户端则针对每帧发出 15,000 到 70,000 次 D3D9 调用的游戏进行了调整。

对上游的更改:

  • 客户端帧步调器(可等待计时器加自旋),因此步调发生在游戏进程而非服务器中。bridge.conf: clientFrameCap
  • 状态块传输计划:为 GTA IV 每帧应用约 475 次的 D3DSBT_ALL 块预计算的脏索引列表
  • StateBatch:渲染、采样器和阶段状态,纹理、着色器、流和着色器常量打包到每次刷新的单条记录中。bridge.conf: clientStateBatch
  • 批处理命令索引发布。bridge.conf: clientCmdPublishBatch
  • 合并的设备/通道锁;无导入自旋锁,因此挂钩 kernel32 的 ASI 加载器无法重入它
  • bridge32.log 中的每窗口等待统计;断言记录器不再解引用失效通道
  • 服务器:StateBatch 重放;vanilla-DXVK 模式作为支持的配置;仅对返回数据的调用进行响应

结果

参考系统:Intel i7-9700K,NVIDIA GeForce RTX 2070 (8 GB),驱动 610.74,2560x1440 无边框窗口,GTA IV CE 1.2.0.59 配合 FusionFix。帧时间是固定 60 秒脚本驾驶过程中的平均值,未锁定帧率。内存数据来自进程内地址空间监视器,视图和细节距离为 100。

  • 进程内 DXVK,相同路线 (6 次运行):16.9 毫秒。视图距离 100 时的最大空闲区域:5 MB
  • b-bridge,上游客户端 (5 次运行):22.4 毫秒。约 800 MB
  • b-bridge,传输计划 + 响应关闭 (4 次运行):18.6 毫秒。约 800 MB
  • b-bridge,最终客户端 (5 次运行):13.6 毫秒。约 800 MB
  • b-bridge,最终客户端,5 GB 纹理包组合:16.4 毫秒。735 至 819 MB

批处理工作是使桥接帧时间低于进程内数值的原因;传输本身需要时间,而客户端通过发送更少但更大的消息来隐藏这一点。图片选项卡中的五个图显示了各阶段帧时间、帧时间分布、地址空间对比、内容和后处理组合的成本以及整个会话中的 GPU 利用率。

局限性

这些是测试过的边界。除此之外的任何情况都不应假定为有效。

  • 仅限 NVIDIA。 所有测量均在一块 RTX 2070 和一个驱动版本上完成。没有 AMD 或 Intel GPU 运行过此构建。DXVK 本身与厂商无关,但桥接服务器的设备创建和交换链路径尚未在任何其他 Vulkan 驱动上测试过。
  • 单机、单配置。 一个 CPU,一种分辨率和刷新率,仅限无边框窗口。附带的 dxvk.conf 禁用了独占全屏,因为模式切换会在进程边界丢失设备。
  • 单一游戏版本和单一模组组合。 通过 ASI 加载器加载 FusionFix 的 GTA IV CE 1.2.0.59。其他补丁级别 (1.0.7.0, 1.0.8.0)、未打补丁的完全版以及通过其自身的 d3d9.dll 加载的 FusionFix 均未测试。
  • 仅光栅化。 GTA IV 是一个延迟渲染器,Remix 路径追踪管线无法与其生成可用图像。该管线未包含在内。
  • CPU 受限场景没有改善。 每个 D3D9 调用仍然跨越进程边界。增益在于地址空间;在受游戏渲染线程限制的场景中,帧时间保持持平,而非减少。
  • 启动不同步,约每十次启动出现一次。 服务器进程从未启动,其日志未写入,客户端在 12 秒后退出。重新启动即可成功。尚未隔离原因。
  • 每次启动时首次设备创建失败。 bridge64.log 显示在创建真实设备之前有一次失败的 CreateDevice (0x8876086c)。这是游戏以零刷新率进行探测所致,无害。
  • 服务器端的覆盖层无法获得输入。 服务器中的 ReShade Vulkan 层可以正确渲染,但其覆盖层和热键无效,因为窗口属于游戏进程。此类工具必须通过文件配置。
  • 仅限 DXVK 3.0.2。 尚未使用此服务器验证更新的 DXVK 版本。
  • 会话时长。 最长的单次测量会话约为 25 分钟。数小时的稳定性尚未表征。

安装

  1. 如果你的 GTAIV\d3d9.dll 是 FusionFix 的包装器(约 175 KB),将其重命名为 d3d9Hooked.dll,并确保存在 dinput8.dll (Ultimate ASI Loader),以便 plugins\GTAIV.EFLC.FusionFix.asi 继续加载。如果是 DXVK,则移除它;服务器现在运行 DXVK。
  2. 将压缩包中的 GTAIV 文件夹复制到你的 GTAIV 文件夹上:d3d9.dll (客户端),dxvk.conf,以及包含 NvRemixBridge.exe (服务器)、d3d9vk_x64.dll (DXVK 3.0.2) 和 bridge.conf 的 .trex\ 文件夹。
  3. 在 dxvk.conf 中保持 dxvk.maxFrameRate 和 dxvk.latencySleep 关闭;在 .trex\bridge.conf 中使用 clientFrameCap 设置帧率上限。以无边框窗口模式运行。
  4. 正常启动。日志:GTAIV\rtx-remix\logs\bridge32.log (客户端) 和 bridge64.log (服务器)。如果游戏约 12 秒后退出且未写入 bridge64.log,请重新启动。

压缩包内的 INSTALL.md 中有完整说明。

可复现性与未来工作

上述数字是一台系统的测量结果,而非规范。任何复现者都应报告 GPU、驱动、分辨率、固定路线上的平均值和 1% 低帧,以及会话期间的最小最大空闲区域。下一步:隔离启动不同步问题,在 AMD 和 Intel 驱动上验证,减少每次调用的客户端开销,表征数小时会话的稳定性。

许可证与致谢

MIT 许可证,与上游相同。NVIDIA bridge-remix (MIT) 提供传输层;DXVK 由 doitsujin 编写 (zlib),未修改地重新分发。名称是 Broker Bridge 的缩写,取自自由城中的那座桥。