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

以编程方式创建directx 11纹理,三种不同方法的优缺点,directx,textures,directx-11,Directx,Textures,Directx 11,说明了在directx 11中,有多种方式以编程方式填充directx 11纹理: (1) 使用默认使用纹理创建纹理,并使用内存中的数据对其进行初始化 (2) 使用动态用法创建纹理,使用DeviceContext Map获取指向纹理内存的指针,写入它,然后使用Unmap指示您已完成(此时我猜它已复制到gpu) (3) 使用暂存用法创建纹理,并遵循与“动态纹理”相同的步骤,但随后调用ID3D11DeviceContext.CopyResource以使用此暂存纹理依次填充(不可变)默认纹理或动态纹理

说明了在directx 11中,有多种方式以编程方式填充directx 11纹理:

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

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

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

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

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

旁注:我已经读到,在分段纹理的上下文中,从gpu读回的内容没有缓冲,因此您必须自己进行双缓冲。但我不知道这是否准确,也不知道它是否适用于使用分段纹理的写作(甚至不知道它的真正含义)


第二点注意:映射方法文档说它获取子资源中数据的指针,并拒绝GPU访问该子资源。当GPU想要访问其底层数据已被Map调用的纹理时,它会做什么?货摊(我这样问是因为这听起来像是我询问的部分利弊)

正确的答案取决于你将使用纹理做什么。这三个选项是将数据从CPU获取到纹理的不同方式。如果这是一个rendertarget,您通常不会从CPU提供初始数据,因此可以忽略这些:创建纹理,并在准备渲染到纹理中时(可能先清除它)

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

如果这只是一个静态纹理(我的意思是,该纹理的读取量远大于写入量),那么您需要一个USAGE\u DEFAULT或USAGE\u IMMUTABLE纹理。与GPU动态使用相比,它们通常针对GPU读取性能进行了优化。如果在创建纹理时手头有数据,则选项(1)最简单,使用的中间内存最少,在DX11中,可以在渲染线程之外的单独线程上完成到GPU的数据传输。如果在创建纹理时没有数据,请在有数据时使用UpdateSubresource()或选项(3)提供数据

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

选项(3)更专业,可用于将初始数据加载到静态纹理中(重用分段曲面加载多个纹理的数据)或用于相对动态使用的流式数据。它为您提供了对GPU/CPU同步和用于传输的中间内存的精确控制。通常,您会使用一个暂存缓冲区环,D3D11_MAP_FLAG_DO_NOT_等待检查每个缓冲区是否仍由以前的CopyResource使用。我认为这是一个专家的选择——如果你不小心,你可以通过防止CPU和GPU异步运行而严重损坏PYF。
充分披露:我在Nvidia从事D3D驱动程序的工作,但这些是我个人的观点。

在学习过程中添加注释。显然,您无法使用上述方法(1)以编程方式创建多采样默认纹理。虽然directx 11中MAP调用中的D3D11_MAP_标志非常模糊,但它显然告诉GPU如果需要映射的资源该怎么做。目前只记录了一个标志,并且不清楚使用0是否意味着暂停。显然,D3D11_USAGE_动态资源的MIP级别必须等于1。