在DirectX12中取消资源映射的好处是什么?



在过去的问题DirectX12上传同步D3D12_HEAP_TYPE_UPLOAD中,我遇到了麻烦,取消了一个上传资源的映射,在命令列表中使用它并执行,然后在gpu使用以前的数据之前再次映射和覆盖

我一定认为第二次映射会给我不同的内存写入,如果gpu没有使用完未映射的数据。

如果不是这样,那么在directX12中取消映射又有什么意义呢?

Chuck Walbourn说

从CPU获取数据并将其复制到'中间'资源(完成后取消映射,因为不需要保留虚拟内存地址分配)。

我想我甚至不知道虚拟内存是否在cpu或gpu内存,(也许它不是在标准的cpu或gpu内存;它在gpu上的一些特殊内存中,或者可能是设备相关的,因此虚拟内存是什么是模糊的)。

首先,我认为有必要解决重新映射的问题。

在DX11中,驱动程序做了所有繁重的工作,所以当你映射(写/丢弃)一个资源时,驱动程序在底层做了一堆工作,特别是分配一个新的缓冲区并返回地址(称为"资源重命名")。驱动程序将跟踪GPU何时使用特定内存位,并将管理何时可以重用未使用的内存。

对于现代api (DX12和Vulkan),当您创建资源时,资源显式地绑定到内存中的位置。它是一个更薄的层(你更接近金属)。映射时,你会得到一个指针。你可以永远保持资源映射,并且返回的指针将始终有效,并且将始终指向GPU将从中读取的内存中的地址。这里的优点是,由于您的应用程序知道它将如何使用这些资源,因此您可以针对您的特定用例进行优化。例如,如果你有一个固定的缓冲区,用于存储每帧更新一次的依赖于视图的数据,并且你要缓冲3帧,你可以创建3个资源,将它们全部映射,并通过它们进行循环——节省API调用的开销等。

在虚拟内存前端,当你映射时,你得到一个指针,它是一个虚拟内存地址,它将被映射到物理的cpu端内存中的某个地方。所以映射肯定是到物理CPU内存。如何将内存映射到GPU可能是设备/系统相关的,但我相信在大多数情况下,内存生活在cpu端内存上,并通过PCIe总线由GPU读取(这就是为什么你上传而不是让GPU直接从该资源读取)。

鉴于大多数应用这些天为64位架构,我们一般不超与虚拟内存地址空间有限,但它仍然不是一个坏主意来清理,如果你不能使用它,因为它仍然是使用资源(虚拟内存映射页表等)。

最新更新