D3D的几个LOCK标志

因为游戏里面绘制Ui,调用lock函数来lock数据buffer的时候用到了如下3个标志。


D3DLOCK 中 D3DLOCK_NOSYSLOCK 

sdk中的原文是:

The default behavior of a video memory lock is to reserve a system-wide critical section, guaranteeing that no display mode changes will occur for the duration of the lock. This option causes the system-wide critical section not to be held for the duration of the lock.

The lock operation is time consuming, but can enable the system to perform other duties, such as moving the mouse cursor. This option is useful for long-duration locks, such as the lock of the back buffer for software rendering that would otherwise adversely affect system responsiveness.

(摘自Microsoft DirectX SDK (August 2009))

网上找到一段中文的解释:执行Lock()函数需要一定的时间,默认状态下,Direct3D会暂停其他的显示操作,直至Lock()函数执行结束。设置D3DLOCK_NOSYSLOCK属性,可以使Direct3D在执行对缓冲区加锁的同时执行其他的显示操作,比如移动鼠标。

两个标志D3DLOCK_NOOVERWRITE。D3DLOCK_DISCARD

Re:请教这两个标志D3DLOCK_NOOVERWRITE。D3DLOCK_DISCARD

前者是向Buffer里面再添加数据,并且能在修改数据的时候继续渲染
后者使用对象是Dynamic,像Dynamic Texture,Dynamic Vertex buffer等等
且在修改数据时,能使用原来的数据进行渲染。当修改里面数据完成时,调用Unlock后,就以新的buffer数据进行渲染

如果不使用任何标志进行Lock的话,将会打断CPU和GPU的并行流水线,使GPU处于Idle状态,直到调用Unlock才会使其(GPU)继续工作。

Re:请教这两个标志D3DLOCK_NOOVERWRITE。D3DLOCK_DISCARD

D3DLOCK_NOOVERWRITE:表示你的程序可以肯定,对于你将要锁定的buffer中进行修改的那部分数据,绝对之前没有在提交的dp范围内,就是绝对不会over write已经dp的数据,这样GPU的DMA操作不会被打断,它可以放心把这个大buffer交给你控制,而你只写入一部分,同时gpu可以读取同一buffer的其他部分(你刚才dp提交的),这样保证gpu和cpu协同工作,没有idle产生。

D3DLOCK_DISCARD:当你对于这个buffer已经有的内容不感兴趣,比如对于cpu驱动的骨骼动画,你cpu保留了所有数据,cpu计算完毕,准备上传新一帧的动画,那就discard原先的数据,那gpu如果用完了buffer,那它直接把这个buffer返回给你,如果它正忙着使用这个buffer,那它给你创建个新buffer,对于而言,这些透明。


这俩flags非常关键,不用不行。特别对于粒子系统这样需要频繁更新的系统,一定要慎重。


To receive a performance improvement when using dynamic vertex buffers, the application must call IDirect3DVertexBuffer9::Lock or IDirect3DIndexBuffer9::Lock with the appropriate flags. D3DLOCK_DISCARD indicates that the application does not need to keep the old vertex or index data in the buffer. If the graphics processor is still using the buffer when lock is called with D3DLOCK_DISCARD, a pointer to a new region of memory is returned instead of the old buffer data. This allows the graphics processor to continue using the old data while the application places data in the new buffer. No additional memory management is required in the application; the old buffer is reused or destroyed automatically when the graphics processor is finished with it. Note that locking a buffer with D3DLOCK_DISCARD always discards the entire buffer, specifying a nonzero offset or limited size field does not preserve information in unlocked areas of the buffer.

There are cases where the amount of data the application needs to store per lock is small, such as adding four vertices to render a sprite. D3DLOCK_NOOVERWRITE indicates that the application will not overwrite data already in use in the dynamic buffer. The lock call will return a pointer to the old data, allowing the application to add new data in unused regions of the vertex or index buffer. The application should not modify vertices or indices used in a draw operation as they might still be in use by the graphics processor. The application should then use D3DLOCK_DISCARD after the dynamic buffer is full to receive a new region of memory, discarding the old vertex or index data after the graphics processor is finished.

原文地址:https://www.cnblogs.com/kex1n/p/2216749.html