D3DLOCK_NOOVERWRITE。D3DLOCK_DISCARD lock 和unlock

这里有点资料,顺便说一下我的理解
CPU 和GPU是可以并行工作的,如果GPU正在使用一块内存上的数据绘制,而CPU要修改这块数据,就会出现CPU等待GPU或GPU等待CPU的情况,造成资源浪费。
如果GPU在使用一块内存的时候,用D3DLOCK_DISCARD标志锁定,表示我们对原来的数据不敢兴趣了,丢弃是相对于我们来说的,GPU会分配一块新内存,用来保存我们更新的数据,这时GPU可以使用原来的内存继续绘制。
用D3DLOCK_NOOVERWRITE锁定表示,我们需要修改数据,并且仍然需要原来的数据,这时锁定GPU占用的内存会失败,并立即返回,如果不用该标志,CPU会等待GPU用完了才返回,如果锁定的内存没有被GPU占用,则会成功锁定。

一点理解仅供参考。

lock和unlock是为了CPU和GPU的同步设计的


 请教这两个标志D3DLOCK_NOOVERWRITE。D3DLOCK_DISCARD

一个是追加写入一个是丢弃吗?但是我搞不懂二者有何不同,主要是使用场合,我把D3DLOCK_NOOVERWRITE 改成 D3DLOCK_DISCARD也可以用。那就都用discard不就好了?弄不清。

 注册: 2008-3    状态: 离线    游戏开发 游戏运营 业余游戏 游戏外包 游戏招聘 楼主   TOP

风之翼CC
Exp:49

侦察兵
 发表于: 2008-4-10 11:22:00
    档案 |  Email |  短信 |  收藏 |  举报 |  引用 |  修改帖子   
Re:请教这两个标志D3DLOCK_NOOVERWRITE。D3DLOCK_DISCARD

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

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

 注册: 2006-12    状态: 离线    游戏开发 游戏运营 业余游戏 游戏外包 游戏招聘 1楼   TOP
youareeverything
Exp:71

侦察兵
 发表于: 2008-4-10 15:45:00
    档案 |  Email |  短信 |  收藏 |  举报 |  引用 |  修改帖子   
Re:请教这两个标志D3DLOCK_NOOVERWRITE。D3DLOCK_DISCARD

前者也是锁定动态的么,书上这么写的。至少我没看出两者实际中效果差别。

 注册: 2008-3    状态: 离线    游戏开发 游戏运营 业余游戏 游戏外包 游戏招聘 2楼   TOP
congy
Exp:1065

中士
 发表于: 2008-4-11 4:18:00
    档案 |  主页 |  短信 |  收藏 |  举报 |  引用 |  修改帖子   
Re:请教这两个标志D3DLOCK_NOOVERWRITE。D3DLOCK_DISCARD

效果当然没差别,渲染效率提高了.

 注册: 2003-8    状态: 离线    游戏开发 游戏运营 业余游戏 游戏外包 游戏招聘 3楼   TOP
wjk98550328
Exp:400

下士
 发表于: 2008-4-11 8:42:00
    档案 |  Email |  短信 |  收藏 |  举报 |  引用 |  修改帖子   
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.


你可能感兴趣的:(D3DLOCK_NOOVERWRITE。D3DLOCK_DISCARD lock 和unlock)