IDirect3DVertexBuffer9::Lock 失败的可能原因有哪些?
在我们游戏的一些最终用户的错误报告中,我经常看到以下行为:IDirect3DVertexBuffer9::Lock
失败,返回的错误代码为 D3DERR_NOTAVAILABLE
。
一旦发生这种情况,经常(但并非总是)紧随其后的是 CreateTexture
或 CreateVertexBuffer
调用失败,并出现错误 D3DERR_OUTOFVIDEOMEMORY
。
顶点缓冲区锁定失败的可能原因有哪些?虚拟内存地址空间是否会被耗尽,或者什么?
In error reports from some end users of our game I have quite often seen following behaviour: IDirect3DVertexBuffer9::Lock
fails, returned error code is D3DERR_NOTAVAILABLE
.
Once this happens, quite frequently (but not always) it is followed by the CreateTexture
or CreateVertexBuffer
call failing with error D3DERR_OUTOFVIDEOMEMORY
.
What are possible reasons for a vertex buffer lock failure? Could the virtual memory address space be exhausted, or what?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
根据 Microsoft Chuck Walbourn 的 DIRECTXDEV 响应,除了“地址空间不足”之外,另一个原因可能是“页面池不足”。
我们确实创建了大量 Direct3D 资源。
Based on the DIRECTXDEV response by Chuck Walbourn from Microsoft, besides of "out of address space" another cause could be "out of page pool".
We DO create a lot of Direct3D resources.
这是我发布到 DirectXDev 的内容:;)
调试运行时是否提供任何有用的信息?
编辑:我能想到的唯一一件事是光圈内存已经用完了。我不知道 PCIExpress 是如何工作的,但在 AGP 上你可以设置孔径大小。但我不知道如何检查它是否已满。我怀疑您看到的错误是报告已满。您是否使用丢弃标志进行了大量锁定?如果是这样,这些可能会在孔径中创建大量新分配,并导致您耗尽内存。然而,这纯粹是猜测。
我猜测如果只有部分用户发生这种情况,那就是低端机器上的用户。如果运行缓慢,那么您最终可能会在命令缓冲区中缓冲大量数据。这将使控制变得迟缓,并且猜测“可能”导致您所看到的问题。您可能想尝试确保命令缓冲区永远不会变得太长。如果您确保在没有丢弃标志(即标志设置为 0)的情况下完成每个帧的第一次锁定,那么这将导致管道停止,直到渲染顶点缓冲区并使命令缓冲区恢复与您同步。这将导致速度减慢,因为命令缓冲将无法轻松消除帧速率峰值......
无论如何......这只是一个猜测!
This is what I posted to DirectXDev: ;)
Does the debug runtime provide any useful information?
Edit: The only other thing I can think of is that the aperture memory has run out. I don't know how this works with PCIExpress but on AGP you can set the aperture size. I've no idea how to check if it is full however. I suspect the error you are seeing is reporting that its full. Are you doing lots of locks with the Discard flag? If so its possible that these are creating tonnes of new allocations in the aperture and is causing you to run out of memory there. This is pure guess work however.
I'd guess that if this is happening with only some of your users it is those on the lower end machines. If things run slowly then you can end up with a lot of data buffered in the command buffer. This will make control laggy and "could", at a guess, lead to the problem you are seeing. You may want to try making sure the command buffer never gets too long. If you make sure the first lock of every frame is done without the discard flag (ie flag set to 0) then this will cause the pipeline to stall until the vertex buffer has been rendered and bring the command buffer back in sync with you. This will cause a slow down as the command buffering will not be able to smooth out frame rate spikes as easily ...
Anyway ... thats just a guess!
提出的有关内存不足的问题是有效的。我们需要有关 Lock() 调用的一些详细信息才能确定,但是例如,如果它位于 DEFAULT 池中并且是动态的(已传递 D3DLOCK_DISCARD 标志),则您的驱动程序很可能会尝试找到一块未使用的内存来返回(因为它在内部进行双倍或三倍缓冲)并且失败,因为正如您很快发现的那样,视频内存已耗尽。
The raised issue about out of memory is valid. We need some details on the Lock() call to be sure, but for example if it is in the DEFAULT pool and if it's dynamic (D3DLOCK_DISCARD flag passed), it's very well possible that your driver tries to find an unused piece of memory to return (because it double or triple buffers internally) and fails because, as you discover yourself soon after, video memory is exhausted.