D3D11_USAGE_STAGING,使用了哪种GPU/CPU内存?

4

我阅读了D3D11 Usage页面。从CUDA背景出发,我想知道标记为D3D11_USAGE_STAGING的纹理会存储到哪种类型的内存中。

我猜测在CUDA中,它会是固定的页面锁定的零拷贝内存。我测量了从具有D3D11_USAGE_STAGINGID3D11Texture2D传输到使用malloc分配的主机缓冲区所需的时间,它花费了近7毫秒(在流媒体/游戏中相当多)。我认为这将是从GPU全局内存到该内存区域所需的时间。

我的任何假设都正确吗?D3D11_USAGE_STAGING使用什么样的GPU内存?


你是如何计时的?从地图上复制完整还是只复制了一部分?(这很重要,排除与等待GPU完成资源相关的时间问题)。 - Varrak
1个回答

12
< p > D3D11_USAGE_STAGING 的主要用途是将数据加载到其他D3D11_USAGE_DEFAULT 池资源中。另一个常见用途是将渲染目标的 'readback' 到 CPU 可访问内存。您可以使用 CopySubResourceRegion 在 DEFAULT 和 STAGING 资源之间移动数据 (离散硬件通常使用直接内存访问来处理在系统内存和 VRAM 之间移动数据)。

这是一般化的说法,因为它取决于体系结构和驱动程序选择,但简而言之:

  • D3D11_USAGE_STAGING 表示将其放入系统内存,GPU 无法访问它。

  • D3D11_USAGE_DEFAULT 将其放入 VRAM,CPU 无法访问它。把数据放入其中需要从 STAGING 资源复制数据。您可以将 UpdateSubresource 视为方便函数,它创建一个 STAGING 资源,将数据复制到该资源中,从 STAGING 复制到 DEFAULT,然后释放 STAGING 副本。

  • 在DirectX 11.2或更高版本中,驱动程序可以选择实现一个可选功能,即使对于D3D11_USAGE_DEFAULT类型的资源,也可以允许CPU访问。这取决于内存系统设置方式(即在统一内存架构中,系统内存和VRAM是相同的)。
  • D3D11_USAGE_IMMUTABLE基本上与D3D11_USAGE_DEFAULT相同,但您只会在创建调用中初始化它一次。

  • D3D11_USAGE_DYNAMIC表示将其放入共享系统内存中,CPU和GPU都需要访问它。与DEFAULT相比,GPU从其中读取的性能通常会有所下降,因此您应该谨慎使用。它主要用于每帧由CPU生成并需要渲染的内容(如地形系统或程序化几何体)。

  • 使用内容流传输的游戏通常具有一组STAGING纹理,它们在后台加载数据,然后将其复制到成为有效渲染的DEFAULT纹理中。这使得它们可以重复使用STAGING和DEFAULT纹理,而无需每帧销毁/创建资源。

    看一下这篇在 Microsoft Docs 上有些过时的文章:资源管理最佳实践


    你能详细说明一下异步分阶段复制吗?在后台加载仍然需要在DeviceContext上使用Map(这不是线程安全的),根据我在其他地方读到的,游戏倾向于在资源创建时使用初始数据? - mrvux
    如果您直接处理同步,仍然可以在多个线程上共享设备上下文,因此某些流式游戏会进行负载分配,提交到工作队列以进行映射等操作。 InitData绝对是另一种方法,但它需要创建和销毁资源,这可能会影响性能。 - Chuck Walbourn

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接