directx - 以编程方式创建 directx 11 纹理,三种不同方法的优缺点

标签 directx textures directx-11

msdn documentation解释了在 directx 11 中,有多种方法可以通过编程方式填充 directx 11 纹理:

(1) 使用默认使用纹理创建纹理并使用内存中的数据对其进行初始化

(2) 创建动态使用的纹理,使用 DeviceContext Map 获取指向纹理内存的指针,写入它,然后使用 Unmap 指示您已完成(此时我猜它已复制到 GPU)

(3) 使用暂存用法创建纹理,并遵循与动态纹理相同的步骤,但随后调用 ID3D11DeviceContext.CopyResource 以使用此暂存纹理依次填充(非不可变)默认或动态纹理。

但是文档根本没有解释每种方法的优缺点,而且我对 directx 还很陌生,所以我根本不清楚。

在 directx 11 中以编程方式创建纹理的每种方法的优缺点是什么?

旁注:我读到,在暂存纹理的上下文中,从 GPU 读取的内容不会被缓冲,因此您必须自己进行双缓冲。但我不知道这是否准确,也不知道它是否适用于使用暂存纹理进行书写(甚至不知道它的真正含义)。

第二个旁注: Map 方法文档表示它获取指向子资源中的数据的指针,并拒绝 GPU 访问该子资源。当GPU想要访问底层数据已经被Map调用的纹理时,它会做什么?失速? (我问这个问题是因为这听起来像是我询问的利弊的一部分)

最佳答案

正确的答案取决于您要使用纹理的用途。这三个选项是将数据从 CPU 获取到纹理的不同方式。如果这是渲染目标,您通常不会提供来自 CPU 的初始数据,因此您可以忽略这些:创建纹理,然后在准备好渲染到其中时(可能先对其进行 Clear() 处理)。

因此,假设您在应用程序内存中确实有想要进入纹理的数据:

如果这只是一个静态纹理(我的意思是读取的纹理比写入的纹理多),那么您需要 USAGE_DEFAULT 或 USAGE_IMMUTABLE 纹理。与 USAGE_DYNAMIC 相比,这些通常针对 GPU 读取性能进行了优化。如果您在创建纹理时手头有数据,那么选项 (1) 最简单,使用最少的中间内存,并且在 DX11 中,可以在与渲染线程不同的单独线程上完成到 GPU 的数据传输。如果您在创建纹理时没有数据,请在有数据时使用 UpdateSubresource() 或选项 (3) 提供数据。

如果它是动态纹理,意味着您经常从 CPU 提供新内容(基于 CPU 的视频播放是典型情况:CPU 每帧提供一次数据,然后 GPU 每帧读取一次),那么您可能想使用 USAGE_DYNAMIC 和选项 (2)。 USAGE_DYNAMIC 纹理针对从 CPU 到 GPU 的流数据进行了优化,而不仅仅是针对 GPU 读取。硬件供应商之间的细节(和性能影响)有所不同,但通常您只想在确实将数据从 CPU 流式传输到 GPU 时才使用 USAGE_DYNAMIC,而不仅仅是因为它是预先加载静态数据的便捷方法。

选项(3)更加专业,可用于将初始数据加载到静态纹理中(重用暂存表面来加载许多纹理的数据)或用于流数据以进行相对动态的使用。它使您能够精确控制 GPU/CPU 同步以及用于传输的中间内存。通常,您会使用一圈暂存缓冲区和 D3D11_MAP_FLAG_DO_NOT_WAIT 来检查每个缓冲区是否仍在被先前的 CopyResource 使用。我认为这是一个专家选项 - 如果您不小心,可能会阻止 CPU 和 GPU 异步运行,从而严重损害性能。

全面披露:我在 Nvidia 从事 D3D 驱动程序的工作,但这些是我个人的观点。

关于directx - 以编程方式创建 directx 11 纹理,三种不同方法的优缺点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6347950/

相关文章:

android - Samsung Galaxy S2 OpenGl ES 2.0 问题

c++ - 如何使用 SDL2 Texture 作为更新 Canvas ?

c++ - 在哪里设置着色器文件的入口点(错误X3501)?

c++ - 当 SampleDesc.Count > 1 时,Direct3D11 DEBUG MODE 在最​​终 COM 版本上崩溃

c++ - 记住创建空白 win32 窗口的所有内容很重要吗

c++ - VS2010、DirectX 和 Intellisense 问题

c++ - 创建一个 1 像素的纹理问题。

c++ - 未解析的外部符号 _D3D10CreateDeviceAndSwapChain@32 在函数“public : bool 中引用

使用 Freetype2 进行 OpenGL 字体渲染

directx - 如何在 DirectX11 中使用翻转模式消除锯齿?