游戏开发论坛

 找回密码
 立即注册
搜索
查看: 6553|回复: 11

FAQ-4 我对D3D中的顶点缓存的概念感到迷惑,特别是其分配

[复制链接]

41

主题

184

帖子

184

积分

注册会员

Rank: 2

积分
184
发表于 2006-12-13 18:44:00 | 显示全部楼层 |阅读模式
我对D3D中的"顶点缓存_vertex buffers"的概念感到迷惑,特别是其分配和锁定的操作,不知道这些名称的含义是什么?

当"allocating vertex buffers_分配顶点缓存"时:

当使用 STATIC标识分配顶点缓存时,这块缓存位于显存中。它的典型应用是只写一次并不被读回内存的情况。
只有当标志 D3DUSAGE_DYNAMIC被设置时 D3DUSAGE_WRITEONLY标志才有意义。
如果使用DYNAMIC标志创建缓存 (使用D3DUSAGE_DYNAMIC创建的缓存) ,并且D3DUSAGE_WRITEONLY 被使用,缓存被分配到显存中。

如果使用DYNAMIC标志创建缓存 (使用D3DUSAGE_DYNAMIC创建的缓存) ,并且D3DUSAGE_WRITEONLY 不被使用, 缓存被分配到AGP 缓存中。(CPU从AGP缓存中读取的速度比显存中快,但比内存慢,是个很好的折中)
如果没有足够的显存,顶点缓存被分配到AGP缓存中;如果AGP缓存也不够时,创建失败,除非使用POOL_ MANAGED 创建。在这种情况下,D3D的运行库会释放足够多的显存,用来创建顶点缓存,并在内存中保存创建的缓存的一个拷贝。那些被运行库释放的显存,在需要它们时可以从内存中复制到显存中。注意标志POOL_ MANAGED 并不被发送到驱动程序,因为这是D3D的附加的功能。

对于NV1X 系列的GPUs, 在进行多数据流渲染得时候,如果有一个顶点缓存位于AGP缓存中,所有的其他位于显存中的顶点缓存会被移动到AGP缓存中。

当" locking vertex buffers_锁定顶点缓存"时:

如果顶点缓存的创建标志是POOL_DEFAULT:

如果没有指定任何标志,程序将被暂停,因为它强制程序和GPU同步操作。->低效



如果指定D3DLOCK_NOOVERWRITE 标志,应用程序不会改变缓存区已存在的内容,运行库会在以后继续使用这块缓存。当应用程序调用这个函数时,驱动程序立即返回。->高效



如果指定D3DLOCK_DISCARD 标志,程序将会更新整个缓存的值,实际上是分配一块新的缓存,即驱动程序重命名它。->高效

[注解:因为CPU和GPU是异步的操作,所以当CPU通过系统总线和GPU同步时,需要等到GPU把当前的工作做完。例如,当GPU正在对一块缓存进行DMA操作时,由于CPU并不对GPU操作的那块缓存进行操作,所以CPU可以和GPU一起工作。当不指定操作标志时,CPU等待GPU完成工作,所以低效。如果指定D3DLOCK_NOOVERWRITE,由于CPU只更新分配的缓存中剩余的缓存,而不更新已经写入的顶点值,所以在CPU写入的时候,GPU可以并行的对那些已经存在的顶点值进行DMA等操作,所以高效;如果使用D3DLOCK_DISCARD 标志,说明当前分配的缓存大小不够了,需要重新分配更大的缓存,CPU对这些新分配的缓存区域进行写操作,GPU这时可能还在异步处理旧的缓存区,所以这种调用也是高效的。调用完毕,收回释放的缓存。]
如果顶点缓存的创建标志是POOL_ MANAGED:

驱动程序对这个标志不做任何响应。

对于这些标志,运行库会在系统内存中创建一个缓存的备份(在必要的时候使用)并且在需要这些缓存的渲染操作,执行的前一刻,把它们从内存复制到显存中。

/******************************************/
I'm confused about vertex buffers in Direct3D. What do the various parameters mean when allocating and locking vertex buffers?

When allocating vertex buffers:

If the buffer is created as STATIC (D3DUSAGE_DYNAMIC not specified), it goes into video memory, period. These vertex buffers are meant to be written once and not read back.

The D3DUSAGE_WRITEONLY flag has a meaning only when the D3DUSAGE_DYNAMIC flag is set.

If the buffer is created as DYNAMIC (D3DUSAGE_DYNAMIC specified) and D3DUSAGE_WRITEONLY is specified, it goes into video memory.

If the buffer is created as DYNAMIC (D3DUSAGE_DYNAMIC specified) and D3DUSAGE_WRITEONLY is not specified, it goes into AGP memory. (CPU reads faster from AGP than video memory, but not as fast as from system memory, good compromise)

If there is no more video memory the buffer goes into AGP memory; if there is no more AGP memory, creation fails unless the buffer’s allocation pool is POOL_ MANAGED in which case the RUNTIME will actually free as many other buffers as necessary until the creation does not fail anymore and keep a copy of the vertex buffer in system memory; the freed buffers will get re-created whenever they are used. Note that the POOL_ MANAGED flag is not passed to the driver.

For NV1X GPUs only, any vertex buffer located in video memory may get demoted to AGP memory in case of multi-stream rendering: If the APPLICATION renders from several vertex buffers and one of them is in AGP memory, every other one that is in video memory will get dumped into AGP.

When locking vertex buffers:

If the vertex buffer’s allocation pool is POOL_DEFAULT:

If no flag is specified: The lock can be blocking because it forces a synch between the GPU and the app -> bad.

If the D3DLOCK_NOOVERWRITE flag is specified, the RUNTIME reuses the locks because the APPLICATION promises not to overwrite data that is being rendered. The DRIVER receives the lock calls, but returns immediately -> efficient.

If the D3DLOCK_DISCARD flag is specified, the APPLICATION will refresh the whole content of the buffer. This allows the DRIVER to rename -> efficient

If the vertex buffer’s allocation pool is POOL_ MANAGED:

The DRIVER never sees the locks on these ones.

For those buffers, the RUNTIME has created a cache in system memory (used to restore the buffer after a driver loss) and updates the DRIVER’s vertex buffer in video memory with the "buffer blit" method right before it is used by a rendering operation.   

8

主题

553

帖子

560

积分

高级会员

Rank: 4

积分
560
发表于 2006-12-13 19:13:00 | 显示全部楼层

Re:FAQ-4 我对D3D中的顶点缓存的概念感到迷惑,特别是其分

如果指定D3DLOCK_NOOVERWRITE 标志,运行库会在以后再次锁定缓存,并且应用程序不会改变缓存的内容。驱动程序受到锁定的函数调用,立即返回这个函数。->高效

If the D3DLOCK_NOOVERWRITE flag is specified, the RUNTIME reuses the locks because the APPLICATION promises not to overwrite data that is being rendered. The DRIVER receives the lock calls, but returns immediately -> efficient.

=======================================================

这翻译,真是昏。

应该是runtime继续使用被lock的buffer,因为应用程序保证不会写“要被HW使用到的区域”。reuse这里做继续使用解,技术文档的翻译来不得意译的。

8

主题

553

帖子

560

积分

高级会员

Rank: 4

积分
560
发表于 2006-12-13 19:16:00 | 显示全部楼层

Re:FAQ-4 我对D3D中的顶点缓存的概念感到迷惑,特别是其分

如果指定D3DLOCK_DISCARD 标志,程序将会更新整个缓存,这允许驱动程序收回这段内存,即重命名它。->高效
If the D3DLOCK_DISCARD flag is specified, the APPLICATION will refresh the whole content of the buffer. This allows the DRIVER to rename -> efficient

=========================================
“这允许驱动程序收回这段内存”,这是你加的吧?实际情况是,不仅memory没有收回,反而有新的memory分配。buffer renaming是一种机制,不光vb/ib有,texture也有,还是不要翻译的好。

41

主题

184

帖子

184

积分

注册会员

Rank: 2

积分
184
 楼主| 发表于 2006-12-13 21:14:00 | 显示全部楼层

Re: Re:FAQ-4 我对D3D中的顶点缓存的概念感到迷惑,特别是其

kypck: Re:FAQ-4 我对D3D中的顶点缓存的概念感到迷惑,特别是其分配和锁定的操作,不知道这些名称的含义是什么?

如果指定D3DLOCK_NOOVERWRITE 标志,运行库会在以后再次锁定缓存,并且应用程序不会改变缓存的内容。驱动程...


已经作了修改,谢谢啊

/*************************/
当" locking vertex buffers_锁定顶点缓存"时:

如果顶点缓存的创建标志是POOL_DEFAULT:

如果没有指定任何标志,程序将被暂停,因为它强制程序和GPU同步操作。->低效


如果指定D3DLOCK_NOOVERWRITE 标志,应用程序不会改变缓存区已存在的内容,运行库会在以后继续使用这块缓存。当应用程序调用这个函数时,驱动程序立即返回。->高效


如果指定D3DLOCK_DISCARD 标志,程序将会更新整个缓存的值,实际上是分配一块新的缓存,即驱动程序重命名它。->高效

[注解:因为CPU和GPU是异步的操作,所以当CPU通过系统总线和GPU同步时,需要等到GPU把当前的工作做完。例如,当GPU正在对一块缓存进行DMA操作时,由于CPU并不对GPU操作的那块缓存进行操作,所以CPU可以和GPU一起工作。当不指定操作标志时,CPU等待GPU完成工作,所以低效。如果指定D3DLOCK_NOOVERWRITE,由于CPU只更新分配的缓存中剩余的缓存,而不更新已经写入的顶点值,所以在CPU写入的时候,GPU可以并行的对那些已经存在的顶点值进行DMA等操作,所以高效;如果使用D3DLOCK_DISCARD 标志,说明当前分配的缓存大小不够了,需要重新分配更大的缓存,CPU对这些新分配的缓存区域进行写操作,GPU这时可能还在异步处理旧的缓存区,所以这种调用也是高效的。调用完毕,收回释放的缓存。]

41

主题

184

帖子

184

积分

注册会员

Rank: 2

积分
184
 楼主| 发表于 2006-12-13 21:18:00 | 显示全部楼层

Re: Re:FAQ-4 我对D3D中的顶点缓存的概念感到迷惑,特别是其

kypck: Re:FAQ-4 我对D3D中的顶点缓存的概念感到迷惑,特别是其分配和锁定的操作,不知道这些名称的含义是什么?

如果指定D3DLOCK_DISCARD 标志,程序将会更新整个缓存,这允许驱动程序收回这段内存,即重命名它。->高效...


谢谢你啊,我已经作了响应的修改了。

因为有一些问题需要讨论,所以才把中/英文同时写出的。不断修改,才能更好么,谢谢你这么仔细的看啊。赫赫

不写出来,问题始终不知道是不会提高的,个人的想法不一样,对同一个问题,多讨论会有很多收获的。

180

主题

3511

帖子

3520

积分

论坛元老

Rank: 8Rank: 8

积分
3520
发表于 2006-12-13 23:34:00 | 显示全部楼层

回 kypck !

你的回帖 每次都是 “画龙点睛”,“一针见血”,“开门见山”......
总之
就是 “极度准确地找到错误的地方”
并且 “极度准确地给以修正”

不愧是我在 GAMERES 上最佩服的一个!

21

主题

230

帖子

230

积分

中级会员

Rank: 3Rank: 3

积分
230
发表于 2006-12-15 01:10:00 | 显示全部楼层

Re:FAQ-4 我对D3D中的顶点缓存的概念感到迷惑,特别是其分

看OPENGL的VB 也能学到不少。
opengl有 N个方法来实现高效率的VB.比如vba,vbo,fence,display list,,每个方法看过来,优点和缺点一分析, 好像现在这个VB分配方法,是经过几个改进变出来似的的。

8

主题

553

帖子

560

积分

高级会员

Rank: 4

积分
560
发表于 2006-12-15 19:17:00 | 显示全部楼层

Re: Re:FAQ-4 我对D3D中的顶点缓存的概念感到迷惑,特别是其

lanlan: Re:FAQ-4 我对D3D中的顶点缓存的概念感到迷惑,特别是其分配和锁定的操作,不知道这些名称的含义是什么?

看OPENGL的VB 也能学到不少。
opengl有 N个方法来实现高效率的VB.比如vba,vbo,fence,display list,,每个方...

你要是真正用过这些,得出的结论显然不是这个。

21

主题

230

帖子

230

积分

中级会员

Rank: 3Rank: 3

积分
230
发表于 2006-12-15 22:17:00 | 显示全部楼层

Re:FAQ-4 我对D3D中的顶点缓存的概念感到迷惑,特别是其分

我没用过。麻烦。这么多方法,象D3D提供一种最好的方法不就得了。
我看了他们的文章,每种方法都有优点和缺点。不过,感觉是一种比一种好。现在DX的这个是最好的方法。
如果我用过会得出什么样得结论?

21

主题

230

帖子

230

积分

中级会员

Rank: 3Rank: 3

积分
230
发表于 2006-12-15 22:20:00 | 显示全部楼层

Re:FAQ-4 我对D3D中的顶点缓存的概念感到迷惑,特别是其分

对VB来说最适合的方法。方法没有什么好坏,放到具体应用上面就有了。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2026-1-26 02:00

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表