在过去的一个问题( DirectX12 Upload Synchronization D3D12_HEAP_TYPE_UPLOAD )中,我很难解开上传资源的映射,在命令列表中使用它并执行,然后在gpu使用以前的数据之前再次映射和重写。
如果gpu没有完成未映射的数据,那么我一定认为第二次映射会给我不同的内存。
如果不是这样的话,那么在directX12中取消映射有什么意义呢?
查克·沃尔博恩
从CPU中获取数据并将其复制到“中间”资源中(完成后取消映射,因为不需要将虚拟内存地址分配保持在周围)。
我想我甚至不知道虚拟内存是在cpu还是gpu内存中(可能不是在标准cpu或gpu内存中;它在gpu上的某些特殊内存中,或者可能是设备依赖的,因此虚拟内存是模糊的)。
发布于 2022-07-06 17:25:34
首先,我认为有必要解决重新映射问题。
在DX11中,驱动程序执行所有的繁重工作,因此当您映射(写/丢弃)一个资源时,驱动程序在引擎盖下执行大量工作,特别是分配一个新缓冲区并返回地址(称为“资源重命名”)。驱动程序将跟踪GPU何时使用特定内存完成,并在未使用内存可以重用时进行管理。
对于现代API( DX12和Vulkan),当您创建资源时,资源显式地绑定到内存中的某个位置。这是一个更薄的层(你离金属更近)。当你映射时,你会得到一个指针。您可以永远保持资源映射,返回的指针将始终有效,并且始终指向GPU将读取的内存中的地址。这里的优点是,由于应用程序知道如何使用这些资源,所以可以针对特定的用例进行优化。例如,如果您有一个用于视图相关数据的常量缓冲区,该数据只需更新一次帧,并且要缓冲3帧,则只需创建3个资源,映射所有资源,并通过它们进行循环--从而节省API调用等的开销。
在虚拟内存方面,当您映射时,您会得到一个指针,它是一个虚拟内存地址,它将被映射到物理的CPU端内存中的某个位置。所以映射肯定是物理CPU内存的映射。内存如何映射到GPU可能与设备/系统有关,但我相信在大多数情况下,内存存在于CPU端内存中,并由GPU通过PCIe总线读取(这就是为什么您上传而不是让GPU直接从该资源读取)。
考虑到现在大多数应用程序都是为64位架构而构建的,我们通常不受虚拟内存地址空间的限制,但是如果您不打算使用虚拟内存地址空间,清理仍然不是一个好主意,因为它仍然在消耗所有的资源(用于虚拟内存映射的页表等等)。
https://stackoverflow.com/questions/72835340
复制相似问题